summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/frontend
diff options
context:
space:
mode:
authorSimon Rettberg2017-06-20 15:36:37 +0200
committerSimon Rettberg2017-06-20 15:36:37 +0200
commitda9e025f2b8aa7984782ea86f534530a7c0972f0 (patch)
treee96701748e4ea8ef5db1c164f99628b739938ec5 /modules-available/locationinfo/frontend
parent[locationinfo] Frontend mostly working again... (diff)
downloadslx-admin-da9e025f2b8aa7984782ea86f534530a7c0972f0.tar.gz
slx-admin-da9e025f2b8aa7984782ea86f534530a7c0972f0.tar.xz
slx-admin-da9e025f2b8aa7984782ea86f534530a7c0972f0.zip
[locationinfo] Finish doorsign.html
Diffstat (limited to 'modules-available/locationinfo/frontend')
-rwxr-xr-xmodules-available/locationinfo/frontend/doorsign.html2759
1 files changed, 1364 insertions, 1395 deletions
diff --git a/modules-available/locationinfo/frontend/doorsign.html b/modules-available/locationinfo/frontend/doorsign.html
index eb15c9d0..a39b982a 100755
--- a/modules-available/locationinfo/frontend/doorsign.html
+++ b/modules-available/locationinfo/frontend/doorsign.html
@@ -20,113 +20,131 @@ optional:
roomupdate: Time the PCs in the room gets updated,in seconds.
rotation:[0-3] rotation of the roomplan
vertical:[true] only mode 1, sets the calendar above the roomplan
- scaledaysauto: [true] if true it finds automaticly the daystoshow parameter depending on display size
+ scaledaysauto: [true] if true it finds automatically the daystoshow parameter depending on display size
-->
<html lang="de">
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">
<head>
<title>DoorSign</title>
- <script type='text/javascript' src='../../../script/jquery.js'></script>
- <script type='text/javascript' src='../../js_jqueryui/clientscript.js'></script>
<link rel='stylesheet' type='text/css' href='../../js_jqueryui/style.css'/>
<link rel='stylesheet' type='text/css' href='jquery-week-calendar/jquery.weekcalendar.css'/>
- <script type='text/javascript' src="jquery-week-calendar/jquery.weekcalendar.js"></script>
<style type='text/css'>
body {
font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
margin: 0;
+ padding: 0;
width: 100%;
height: 100%;
- float: left;
- box-sizing: border-box;
-
background-color: #cacaca;
overflow: hidden;
position: absolute;
display: table;
-
}
.row {
- background-color: #404040;
+ background-color: #444;
box-shadow: 0 0.1875rem 0.375rem rgba(0, 0, 0, 0.25);
margin-bottom: 4px;
-
width: 100%;
-
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ justify-content: space-between;
}
- .header {
- display: table;
+ .col {
+ padding: 0 4px;
color: white;
- padding: 0;
+ overflow: hidden;
+ flex: 1 1 auto;
+ text-overflow: ellipsis;
+ }
+
+ .col-square {
+ width: 4vw;
+ height: 4vw;
+ font-size: 2.5vw;
+ flex: 0 0 auto;
+ text-align: center;
+ padding: 5px 0 0 0;
+ }
+
+ .count-1 .col-square {
+ width: 8vw;
height: 8vw;
+ font-size: 6vw;
+ }
+ .count-2 .col-square {
+ width: 6vw;
+ height: 6vw;
+ font-size: 4.5vw;
}
.progressbar {
- width: 0px;
+ width: 0;
height: 2px;
position: absolute;
background-color: red;
- bottom: 0px;
+ bottom: 0;
z-index: 100;
}
- .font {
- display: table-cell;
- vertical-align: middle;
+ .header-font {
font-size: 3vw;
- font-weight: bold
+ font-weight: bold;
}
- .courseText {
- text-align: center;
+ .nowrap {
+ white-space: nowrap;
+ overflow: hidden;
}
- .row::after {
- content: "";
- clear: both;
- display: block;
+ .timer {
+ color: #ddd;
}
- [class|="col"] {
- float: left;
- padding: 0;
- box-sizing: border-box;
+ .count-2 .header-font {
+ font-size: 1.8vw;
}
- .col-1 {
- width: 33%;
+ .count-3 .header-font {
+ font-size: 1.2vw;
}
- .col-2 {
- width: 33%;
+ .count-1 .header-font {
+ font-size: 1.5vw;
}
- .roomLayoutDesign {
- position: relative;
- float: left;
- boxSizing: border-box;
+ .seats-counter {
+ color: white;
+ margin: auto;
+ padding: 0;
+ font-weight: bold;
+ overflow: visible;
+ height: 100%;
+ text-shadow: #000 2px 2px;
}
- .roompadding {
- float: left;
- position: relative;
+ .center {
+ text-align: center;
}
- .room {
+ .room-layout {
position: relative;
+ float: left;
+ }
+
+ .location-container {
+ position: absolute;
background-color: white;
width: 100%;
height: 100%;
overflow: hidden;
- border-width: 1px;
- border-color: darkgrey;
- border-style: solid;
+ border: 1px solid darkgrey;
}
@@ -155,28 +173,7 @@ optional:
text-shadow: none;
}
- .square {
- display: table;
- float: right;
- padding: 0;
- width: 8vw;
- height: 8vw;
- }
-
- .FreeSeatsFont {
- display: table-cell;
- vertical-align: middle;
- font-size: 6vw;
- color: white;
- top: 0;
- margin: 0 auto;
- position: relative;
- text-align: center;
- font-weight: bold;
- overflow: visible;
- }
-
- .PCImgDiv {
+ .pc-container {
position: absolute;
left: 0;
bottom: 0;
@@ -184,7 +181,7 @@ optional:
}
- .OverlayDiv {
+ .pc-overlay-container {
position: absolute;
left: 0;
bottom: 0;
@@ -193,7 +190,7 @@ optional:
display: table;
}
- .pcImg {
+ .pc-img {
position: absolute;
left: 0;
top: 0;
@@ -219,10 +216,6 @@ optional:
float: left;
}
- .wc-scrollable-grid {
-
- }
-
.ui-widget-content .ui-state-active {
font-weight: bold;
color: black;
@@ -242,25 +235,7 @@ optional:
}
.ui-corner-all {
- moz-border-radius-bottomright: 0;
- webkit-border-bottom-right-radius: 0;
- -khtml-border-bottom-right-radius: 0;
- border-bottom-right-radius: 0;
-
- moz-border-radius-topright: 0;
- webkit-border-top-right-radius: 0;
- -khtml-border-top-right-radius: 0;
- border-top-right-radius: 0;
-
- moz-border-radius-bottomleft: 0;
- webkit-border-bottom-left-radius: 0;
- -khtml-border-bottom-left-radius: 0;
- border-bottom-left-radius: 0;
-
- moz-border-radius-topleft: 0;
- webkit-border-left-right-radius: 0;
- -khtml-border-left-right-radius: 0;
- border-top-left-radius: 0;
+ border-radius: 0;
}
.wc-scrollable-grid .wc-day-column-first {
@@ -268,1440 +243,1434 @@ optional:
}
- [class*="wc-day-"] {
+ [class|="wc-day"] {
border-color: grey;
}
</style>
- <script type='text/javascript'>
-
- var rooms = {};
- var lastRoomUpdate = 0;
- var lastCalendarUpdate = 0;
- var lastSwitchTime = 0;
- var globalConfig = {};
- var roomIds = [];
- var panelUuid = false;
- var supportSvg = typeof SVGRect !== "undefined";
- // TODO: Get languages from slx-admin
- var translation = {
- "en": {
- "room": "Room",
- "closed": "Closed",
- "free": "Free",
- "shortDays": ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
- "longDays": ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- "to": "to"
-
- },
- "de": {
- "room": "Raum",
- "closed": "Geschlossen",
- "free": "Frei",
- "shortDays": ["Son", "Mon", "Die", "Mit", "Don", "Frei", "Sam"],
- "longDays": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
- "to": "bis"
- },
- "pt": {
- "room": "Quarto",
- "closed": "Fechado",
- "free": "Livre",
- "shortDays": ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Se', 'Sáb'],
- "longDays": ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira',
- 'Sexta-feira', 'Sábado'],
- "to": "para"
- }
- };
+ <script type='text/javascript' src='../../../script/jquery.js'></script>
+ <script type='text/javascript' src='../../js_jqueryui/clientscript.js'></script>
+ <script type='text/javascript' src="jquery-week-calendar/jquery.weekcalendar.js"></script>
+</head>
+<body>
+</body>
- $(document).ready(function () {
- var uuid = getUrlParameter("uuid");
- if (!uuid) {
- console.log('No panel uuid given');
- $("body").empty().append($('<h1>').text('No panel UUID given.'));
- return;
- }
- getConfig(uuid);
- });
+<script type='text/javascript'>
+
+ var rooms = {};
+ var lastRoomUpdate = 0;
+ var lastCalendarUpdate = 0;
+ var lastSwitchTime = 0;
+ var hasMode4 = false;
+ var globalConfig = {};
+ var roomIds = [];
+ var panelUuid = false;
+ var supportSvg = typeof(SVGRect) !== "undefined";
+ // TODO: Get languages from slx-admin
+ var translation = {
+ "en": {
+ "room": "Room",
+ "closed": "Closed",
+ "free": "Free",
+ "shortDays": ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ "longDays": ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ "to": "to"
+
+ },
+ "de": {
+ "room": "Raum",
+ "closed": "Geschlossen",
+ "free": "Frei",
+ "shortDays": ["Son", "Mon", "Die", "Mit", "Don", "Frei", "Sam"],
+ "longDays": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
+ "to": "bis"
+ },
+ "pt": {
+ "room": "Quarto",
+ "closed": "Fechado",
+ "free": "Livre",
+ "shortDays": ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Se', 'Sáb'],
+ "longDays": ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira',
+ 'Sexta-feira', 'Sábado'],
+ "to": "para"
+
+ }
+ };
+
+ $(document).ready(function () {
+ var uuid = getUrlParameter("uuid");
+ if (!uuid) {
+ console.log('No panel uuid given');
+ $("body").empty().append($('<h1>').text('No panel UUID given.'));
+ return;
+ }
+ getConfig(uuid);
+ });
+
+ /**
+ * Display given error message and try reloading page once a minute
+ */
+ function fatalError(message) {
+ $('body').empty().append($('<h1>').text(message));
+ window.setInterval(function () {
+ $.ajax('/').done(function () {
+ window.location.reload(true);
+ }).fail(function () {
+ $('body').append('...');
+ });
+ }, 60000);
+ }
+
+
+ /**
+ * Downloads the config of a room, also reloads the page if the config hase changed over time
+ * @param uuid ID of the room
+ */
+
+ function getConfig(uuid) {
+ $.ajax({
+ url: "../../../api.php?do=locationinfo&get=config&uuid=" + uuid,
+ dataType: 'json',
+ cache: false,
+ timeout: 30000,
+ success: function (result) {
+
+ if (!result.locations || result.locations.constructor !== Array) {
+ fatalError("Requested panel doesn't contain locations / not array");
+ return;
+ }
- /**
- * Display given error message and try reloading page once a minute
- */
- function fatalError(message) {
- $('body').empty().append($('<h1>').text(message));
- window.setInterval(function () {
- $.ajax('/').done(function () {
- window.location.reload(true);
- }).fail(function () {
- $('body').append('...');
+ var fetchedRooms = result.locations.filter(function (x) {
+ // filter out if no numeric id, or id already present, or already got 4 locations
+ if (typeof(x.id) !== 'number' || x.id <= 0 || roomIds.indexOf(x.id) !== -1 || roomIds.length >= 4)
+ return false;
+ roomIds.push(x.id);
+ return true;
});
- }, 60000);
- }
+ if (roomIds.length === 0) {
+ fatalError("List of location ids is empty");
+ return;
+ }
- /**
- * Downloads the config of a room, also reloads the page if the config hase changed over time
- * @param uuid ID of the room
- * @param room Room Object, only needed if it already exists
- */
+ var time = new Date(result.time);
+ if (isNaN(time.getTime()) || time.getYear() < 2010) {
+ time = new Date();
+ }
+ SetUpDate(time);
+ delete result.time;
+ delete result.locations;
- function getConfig(uuid) {
- $.ajax({
- url: "../../../api.php?do=locationinfo&get=config&uuid=" + uuid,
- dataType: 'json',
- cache: false,
- timeout: 30000,
- success: function (result) {
+ globalConfig = result;
+ sanitizeGlobalConfig();
+ lastRoomUpdate = MyDate().getTime();
- if (!result.locations || result.locations.constructor !== Array) {
- fatalError("Requested panel doesn't contain locations / not array");
- return;
- }
+ for (var i = 0; i < fetchedRooms.length; ++i) {
+ addRoom(fetchedRooms[i]);
+ }
- var fetchedRooms = result.locations.filter(function (x) {
- // filter out if no numeric id, or id already present, or already got 4 locations
- if (typeof(x.id) !== 'number' || x.id <= 0 || roomIds.indexOf(x.id) !== -1 || roomIds.length >= 4)
- return false;
- roomIds.push(x.id);
- return true;
- });
+ initRooms();
+ // TODO: Check for changed config using get=timestamp and reload whole page on change
+ panelUuid = uuid;
+
+ }, error: function () {
+ fatalError('Could not fetch panel config');
+ }
+ })
+ }
+
+ const PARAM_STRING = 1;
+ const PARAM_INT = 2;
+ const PARAM_BOOL = 3;
+
+ /**
+ * Read given parameter from URL, replacing it in the config object if present.
+ * @param config object config object
+ * @param property string name of property in object, URL param of same name is being checked
+ * @param paramType int one of PARAM_STRING, PARAM_INT, PARAM_BOOL
+ * @param intScaleFactor int optional scale factor that will be applied if paramType == PARAM_INT
+ */
+ function setRoomConfigFromUrl(config, property, paramType, intScaleFactor) {
+ var val = getUrlParameter(property);
+ if (val === true || val === false)
+ return;
+ if (paramType === PARAM_STRING) {
+ config[property] = val;
+ } else if (paramType === PARAM_INT) {
+ config[property] = parseInt(val);
+ if (intScaleFactor) {
+ config[property] *= intScaleFactor;
+ }
+ } else if (paramType === PARAM_BOOL) {
+ val = val.toLowerCase();
+ config[property] = val.length > 0 && val !== 'false' && val !== 'off' && val !== '0';
+ } else {
+ console.log('Invalid paramType: ' + paramType);
+ }
+ }
+
+ /**
+ * Put given numeric config property in range min..max (both inclusive),
+ * if not in range, set to default.
+ * @param config - object config object
+ * @param property - string config property
+ * @param min int - min allowed value (inclusive)
+ * @param max int - max allowed value (inclusive)
+ * @param defaultval - default value to use if out of range
+ * @param scaleFactor int - optional scale factor to apply
+ */
+ function putInRange(config, property, min, max, defaultval, scaleFactor) {
+ var v = config[property];
+ if (!scaleFactor) {
+ scaleFactor = 1;
+ }
+ if (!v || !isFinite(v) || isNaN(v) || v < min * scaleFactor || v > max * scaleFactor) {
+ config[property] = defaultval * scaleFactor;
+ }
+ }
+
+ /**
+ * gets Additional Parameters from the URL, and from the
+ * downloaded json.
+ * also makes sure parameters are in a given range
+ */
+ function sanitizeGlobalConfig() {
+ sanitizeConfig(globalConfig);
+ $('html').attr('lang', globalConfig.language);
+ }
+
+ function sanitizeConfig(config) {
+ if (config) {
+ config.switchtime = config.switchtime * 1000;
+ config.calupdate = config.calupdate * 60 * 1000;
+ config.roomupdate = config.roomupdate * 1000;
+ }
+
+ setRoomConfigFromUrl(config, 'calupdate', PARAM_INT, 60 * 1000);
+ setRoomConfigFromUrl(config, 'roomupdate', PARAM_INT, 1000);
+ setRoomConfigFromUrl(config, 'daystoshow', PARAM_INT);
+ setRoomConfigFromUrl(config, 'scaledaysauto', PARAM_BOOL);
+ setRoomConfigFromUrl(config, 'vertical', PARAM_BOOL);
+ setRoomConfigFromUrl(config, 'eco', PARAM_BOOL);
+
+ setRoomConfigFromUrl(config, 'scale', PARAM_INT);
+ setRoomConfigFromUrl(config, 'rotation', PARAM_INT);
+ setRoomConfigFromUrl(config, 'switchtime', PARAM_INT, 1000);
+
+ // parameter validation
+ putInRange(config, 'switchtime', 5, 120, 6, 1000);
+ putInRange(config, 'scale', 10, 90, 50);
+ putInRange(config, 'daystoshow', 1, 7, 7);
+ putInRange(config, 'roomupdate', 15, 5 * 60, 60, 1000);
+ putInRange(config, 'calupdate', 1, 60, 30, 60 * 1000);
+ putInRange(config, 'mode', 1, 4, 1);
+ putInRange(config, 'rotation', 0, 3, 0);
+ }
+
+ /**
+ * generates the Room divs and calls the needed functions depending on the rooms mode
+ */
+ function initRooms() {
+
+ var width = "100%";
+ var height = "100%";
+ var top, left;
+ hasMode4 = (globalConfig.mode === 4);
+ if (roomIds.length === 2 || roomIds.length === 4) {
+ width = "50%";
+ }
+ if (roomIds.length === 3) {
+ width = "33%";
+ }
+ if (roomIds.length === 4) {
+ height = "50%";
+ }
+ for (var t = 0; t < roomIds.length; t++) {
+ var rid = roomIds[t];
+ var room = rooms[rid];
+ if (roomIds.length === 3) {
+ top = 0;
+ left = (t * 33) + '%';
+ } else {
+ top = (Math.floor(t / 2) * 50) + '%';
+ left = ((t % 2) * 50) + '%';
+ }
- if (roomIds.length === 0) {
- fatalError("List of location ids is empty");
- return;
- }
+ var $loc = $("<div>").prop('id', "location_" + rid).addClass('location-container');
+ $loc.css({top: top, left: left, width: width, height: height});
+ $("body").append($loc);
+ room.$.container = $loc;
- var time = new Date(result.time);
- if (isNaN(time.getTime()) || time.getYear() < 2010) {
- time = new Date();
- }
- SetUpDate(time);
- delete result.time;
- delete result.locations;
+ room.$.locationName = $('<div>').addClass('col').addClass('header-font');
- globalConfig = result;
- sanitizeGlobalConfig();
- lastRoomUpdate = MyDate().getTime();
+ room.$.currentEvent = $("<span>").addClass('nowrap');
+ room.$.currentRemain = $("<span>").addClass('nowrap').addClass('timer');
- for (var i = 0; i < fetchedRooms.length; ++i) {
- var r = addRoom(fetchedRooms[i]);
- }
+ room.$.seatsCounter = $('<span>').addClass('seats-counter');
+ room.$.seatsBackground = $('<div>').addClass('col col-square').append(room.$.seatsCounter);
- initRooms();
- // TODO: Check for changed config using get=timestamp and reload whole page on change
- panelUuid = uuid;
+ var $header = $('<div>').addClass('row').addClass('count-' + roomIds.length);
+ $header.append(room.$.locationName);
+ $header.append($('<div>').addClass('col header-font center').append(room.$.currentEvent).append(' ').append(room.$.currentRemain));
+ $header.append(room.$.seatsBackground);
- }, error: function () {
- fatalError('Could not fetch panel config');
- }
- })
- }
-
- const PARAM_STRING = 1;
- const PARAM_INT = 2;
- const PARAM_BOOL = 3;
-
- /**
- * Read given parameter from URL, replacing it in the config object if present.
- * @param config object config object
- * @param property string name of property in object, URL param of same name is being checked
- * @param paramType int one of PARAM_STRING, PARAM_INT, PARAM_BOOL
- * @param intScaleFactor int optional scale factor that will be applied if paramType == PARAM_INT
- */
- function setRoomConfigFromUrl(config, property, paramType, intScaleFactor) {
- var val = getUrlParameter(property);
- if (val === true || val === false)
- return;
- if (paramType === PARAM_STRING) {
- config[property] = val;
- } else if (paramType === PARAM_INT) {
- config[property] = parseInt(val);
- if (intScaleFactor) {
- config[property] *= intScaleFactor;
- }
- } else if (paramType === PARAM_BOOL) {
- val = val.toLowerCase();
- config[property] = val.length > 0 && val !== 'false' && val !== 'off' && val !== '0';
- } else {
- console.log('Invalid paramType: ' + paramType);
- }
- }
+ $loc.append($header);
+ room.$.header = $header;
- /**
- * Put given numeric config property in range min..max (both inclusive),
- * if not in range, set to default.
- * @param config - object config object
- * @param property - string config property
- * @param min int - min allowed value (inclusive)
- * @param max int - max allowed value (inclusive)
- * @param defaultval - default value to use if out of range
- * @param scaleFactor int - optional scale factor to apply
- */
- function putInRange(config, property, min, max, defaultval, scaleFactor) {
- var v = config[property];
- if (!scaleFactor) {
- scaleFactor = 1;
- }
- if (!v || !isFinite(v) || isNaN(v) || v < min * scaleFactor || v > max * scaleFactor) {
- config[property] = defaultval * scaleFactor;
+ if (room.name !== null) {
+ room.$.locationName.text(room.name);
}
- }
- /**
- * gets Additional Parameters from the URL, and from the
- * downloaded json.
- * also makes sure parameters are in a given range
- */
- function sanitizeGlobalConfig() {
- if (globalConfig) {
- globalConfig.switchtime = globalConfig.switchtime * 1000;
- globalConfig.calupdate = globalConfig.calupdate * 60 * 1000;
- globalConfig.roomupdate = globalConfig.roomupdate * 1000;
- }
+ if (room.config.mode === 1) {
+ setUpCalendar(room.config.scale + "%", room.config.daystoshow, rooms[rid]);
+ initRoomLayout(rooms[rid]);
- setRoomConfigFromUrl(globalConfig, 'mode', PARAM_INT);
- setRoomConfigFromUrl(globalConfig, 'calupdate', PARAM_INT, 60 * 1000);
- setRoomConfigFromUrl(globalConfig, 'roomupdate', PARAM_INT, 1000);
- setRoomConfigFromUrl(globalConfig, 'daystoshow', PARAM_INT);
- setRoomConfigFromUrl(globalConfig, 'scaledaysauto', PARAM_BOOL);
- setRoomConfigFromUrl(globalConfig, 'vertical', PARAM_BOOL);
- setRoomConfigFromUrl(globalConfig, 'eco', PARAM_BOOL);
-
- setRoomConfigFromUrl(globalConfig, 'scale', PARAM_INT);
- setRoomConfigFromUrl(globalConfig, 'rotation', PARAM_INT);
- setRoomConfigFromUrl(globalConfig, 'switchtime', PARAM_INT, 1000);
-
- // parameter validation
- putInRange(globalConfig, 'switchtime', 5, 120, 6, 1000);
- putInRange(globalConfig, 'scale', 10, 90, 50);
- putInRange(globalConfig, 'daystoshow', 1, 7, 7);
- putInRange(globalConfig, 'roomupdate', 15, 5 * 60, 60, 1000);
- putInRange(globalConfig, 'calupdate', 1, 60, 30, 60 * 1000);
- putInRange(globalConfig, 'mode', 1, 4, 1);
- putInRange(globalConfig, 'rotation', 0, 3, 0);
-
- $('html').attr('lang', globalConfig.language);
- }
-
- /**
- * generates the Room divs and calls the needed functions depending on the rooms mode
- */
- function initRooms() {
-
- var width = "100%";
- var height = "100%";
- var hasMode4 = (globalConfig.mode === 4);
- if (roomIds.length === 2 || roomIds.length === 4) {
- width = "50%";
- }
- if (roomIds.length === 3) {
- width = "33%";
- }
- if (roomIds.length === 4) {
- height = "50%";
- }
- for (var t = 0; t < roomIds.length; t++) {
- var headers;
- var rid = roomIds[t];
- var text = "<div class='roompadding' id='roompadding_" + rid + "'></div>";
- $("body").append(text);
-
-
- var obj = document.getElementById("roompadding_" + rid);
- obj.style.height = height;
- obj.style.width = width;
- text = "<div class='room' id ='room_" + rid + "'></div>";
-
- $("#roompadding_" + rid).append(text);
-
-
- text = "<div id='header_" + rid + "' class='row'>" +
- "<div class='header col-2'>" +
- "<div class='font' id='roomHeader_" + rid + "'></div>" +
- "</div>" +
- "<div class='col-1 courseText header'>" +
- "<div class='font' id='courseHeading_" + rid + "'></div>" +
- "</div>" +
- "<div class='square .col-2' id='square_" + rid + "'>" +
- "<div class='FreeSeatsFont' id='freeSeatsHeader_" + rid + "'></div>" +
- "</div>" +
- "</div>";
- $("#room_" + rid).append(text);
-
- if (rooms[rid].name !== null) {
- $("#roomHeader_" + rid).text(rooms[rid].name);
- }
+ } else if (room.config.mode === 2) {
+ setUpCalendar("100%", room.config.daystoshow, rooms[rid]);
- if (roomIds.length === 2) {
- document.getElementById("square_" + rid).style.width = "6vw";
- document.getElementById("square_" + rid).style.height = "6vw";
- document.getElementById("roomHeader_" + rid).style.fontSize = "1.8vw";
- document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "4.5vw";
- document.getElementById("courseHeading_" + rid).style.fontSize = "1.8vw";
- headers = document.getElementsByClassName('header');
- for (var j = 0; j < headers.length; j++) {
- headers[j].style.height = "6vw";
- }
- }
- if (roomIds.length === 3) {
- document.getElementById("square_" + rid).style.width = "4vw";
- document.getElementById("square_" + rid).style.height = "4vw";
- document.getElementById("roomHeader_" + rid).style.fontSize = "1.2vw";
- document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "2.5vw";
- document.getElementById("courseHeading_" + rid).style.fontSize = "1.2vw";
- headers = document.getElementsByClassName('header');
- for (var j = 0; j < headers.length; j++) {
- headers[j].style.height = "4vw";
- }
+ } else if (room.config.mode === 3) {
+ initRoomLayout(rooms[rid]);
- }
- if (roomIds.length === 4) {
- document.getElementById("square_" + rid).style.width = "4vw";
- document.getElementById("square_" + rid).style.height = "4vw";
- document.getElementById("roomHeader_" + rid).style.fontSize = "1.5vw";
- document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "2.5vw";
- document.getElementById("courseHeading_" + rid).style.fontSize = "1.5vw";
-
- headers = document.getElementsByClassName('header');
- for (var j = 0; j < headers.length; j++) {
- headers[j].style.height = "4vw";
- }
- }
+ } else if (room.config.mode === 4) {
+ setUpCalendar("100%", room.config.daystoshow, rooms[rid]);
+ initRoomLayout(rooms[rid]);
+ hasMode4 = true;
+ }
+ SetOpeningTimes(rooms[rid]);
+ UpdateRoomHeader(rooms[rid]);
+ (function (room) {
+ setTimeout(function () {
+ resizeIfRequired(room);
+ }, 800);
+ })(room);
+ }
- if (globalConfig.mode === 1) {
- setUpCalendar(globalConfig.scale + "%", globalConfig.daystoshow, rooms[rid]);
- initRoomLayout(rooms[rid]);
+ if (hasMode4) {
+ generateProgressBar();
+ }
- } else if (globalConfig.mode === 2) {
- setUpCalendar("100%", globalConfig.daystoshow, rooms[rid]);
+ setInterval(mainUpdateLoop, 1000);
+ }
- } else if (globalConfig.mode === 3) {
- initRoomLayout(rooms[rid]);
+ var timeSteps = 10;
+ var lastDate = false;
+ /**
+ * Main Update loop, this loop runs every 1 seconds and calls all
+ * function which should be called periodically
+ */
+ function mainUpdateLoop() {
+ var date = MyDate();
+ var now = date.getTime();
+ // check every 10 sec if rooms need new calendar data or room data
+ // groups request
- } else if (globalConfig.mode === 4) {
- setUpCalendar("100%", globalConfig.daystoshow, rooms[rid]);
- initRoomLayout(rooms[rid]);
- hasMode4 = true;
- }
- SetOpeningTimes(rooms[rid]);
- UpdateRoomHeader(rooms[rid]);
- }
+ if (timeSteps > 9) {
+ timeSteps = 0;
- if (hasMode4) {
- generateProgressBar();
+ if (lastCalendarUpdate + globalConfig.calupdate < now) {
+ lastCalendarUpdate = now;
+ queryCalendars();
}
- setInterval(mainUpdateLoop, 1000);
- }
-
- var timeSteps = 10;
- var lastDate = false;
- /**
- * Main Update loop, this loop runs every 1 seconds and calls all
- * function which should be called periodically
- */
- function mainUpdateLoop() {
- var date = MyDate();
- var now = date.getTime();
- // check ervery 10 sec if rooms need new calendar data or room data
- // groups request
-
- if (timeSteps > 9) {
- timeSteps = 0;
-
- if (lastCalendarUpdate + globalConfig.calupdate < now) {
- lastCalendarUpdate = now;
- queryCalendars();
- }
- if (lastRoomUpdate + globalConfig.roomupdate < now) {
- lastRoomUpdate = now;
- queryRooms();
- }
+ if (lastRoomUpdate + globalConfig.roomupdate < now) {
+ lastRoomUpdate = now;
+ queryRooms();
}
+ }
-
- // switches calendar and roomlayout in mode 4
- if (globalConfig.mode === 4 && lastSwitchTime + globalConfig.switchtime < now) {
- doSwitch = true;
- lastSwitchTime = now;
+ for (var property in rooms) {
+ if (rooms[property].state.end) {
+ // Updating All room Headers
+ UpdateRoomHeader(rooms[property]);
}
+ }
- for (var property in rooms) {
- if (rooms[property].state.end) {
- // Updating All room Headers
- UpdateRoomHeader(rooms[property]);
- }
+ // reload site at midnight
+ var today = date.getDate();
+ if (lastDate !== false) {
+ if (lastDate !== today) {
+ location.reload(true);
}
+ } else {
+ lastDate = today;
+ }
+ timeSteps++;
- // reload site at midnight
- var today = date.getDate();
- if (lastDate !== false) {
- if (lastDate !== today) {
- location.reload(true);
+ }
+
+ /**
+ * Generates a room Object and adds it to the rooms array
+ * @param roomData Config Json of the room
+ */
+ function addRoom(roomData) {
+ var mergedConfig = {};
+ if (roomData.config && typeof(roomData.config.constructor) === 'object') {
+ mergedConfig = roomData.config;
+ sanitizeConfig(mergedConfig);
+ }
+ for (var k in globalConfig) {
+ if (typeof mergedConfig[k] === 'undefined') {
+ mergedConfig[k] = globalConfig[k];
+ }
+ }
+ var now = MyDate().getTime();
+ var room = {
+ id: roomData.id,
+ name: roomData.name,
+ config: mergedConfig,
+ timetable: null,
+ currentEvent: null,
+ nextEventEnd: null,
+ timeTilFree: null,
+ state: null,
+ rawOpeningTimes: roomData.openingtime || null,
+ openingTimes: null,
+ openTimes: 24,
+ currentfreePcs: 0,
+ layout: roomData.machines || null,
+ freePcs: 0,
+ resizeRoom: true,
+ resizeCalendar: true,
+ lastCalendarUpdate: now,
+ lastRoomUpdate: now,
+ $: {},
+ getState: function () {
+ if (this.state === null) {
+ ComputeCurrentState(this);
+ return this.state;
}
- } else {
- lastDate = today;
- }
- timeSteps++;
-
- }
-
- /**
- * Generates a room Object and adds it to the rooms array
- * @param roomData Config Json of the room
- */
- function addRoom(roomData) {
- var now = MyDate().getTime();
- var room = {
- id: roomData.id,
- name: roomData.name,
- config: globalConfig,
- timetable: null,
- currentEvent: null,
- nextEventEnd: null,
- timeTilFree: null,
- state: null,
- rawOpeningTimes: roomData.openingtime || null,
- openingTimes: null,
- openTimes: 24,
- currentfreePcs: 0,
- layout: roomData.machines || null,
- freePcs: 0,
- resized: true,
- lastCalendarUpdate: now,
- lastRoomUpdate: now,
- getState: function () {
- if (this.state === null) {
+ if (this.state.end) {
+ if (this.state.end < MyDate()) {
ComputeCurrentState(this);
- return this.state;
- }
- if (this.state.end) {
- if (this.state.end < MyDate()) {
- ComputeCurrentState(this);
- }
}
- return this.state;
}
+ return this.state;
+ }
- };
- rooms[roomData.id] = room;
- return room;
- }
-
- /**
- * inilizes the Calendar for an room
- * @param percent Percentages of how mucht width the Calendar div should get (only used in mode 1)
- * @param daysToShow How many days the calendar should show
- * @param room Room Object
- */
- function setUpCalendar(percent, daysToShow, room) {
- generateCalendarDiv(percent, room);
- var $calendar = $("#calendar_" + room.id).weekCalendar({
- timeslotsPerHour: 1,
- timeslotHeight: 30,
- daysToShow: daysToShow,
- height: function ($calendar) {
- var height = $(window).height();
- if (roomIds.length == 4) {
- height = height / 2;
- }
-
- height = height - document.getElementById('header_' + room.id).clientHeight - 5;
- if (room.config.mode == 1 && room.config.vertical) {
- height = height * (room.config.scale / 100)
- }
- return height;
- },
- eventRender: function (calEvent, $event) {
- if (calEvent.end.getTime() < MyDate().getTime()) {
- $event.css("backgroundColor", "#aaa");
- $event.find(".time").css({"backgroundColor": "#999", "border": "1px solid #888"});
- } else if (calEvent.end.getTime() > MyDate().getTime() && calEvent.start.getTime() < MyDate().getTime()) {
- $event.css("backgroundColor", "#25B002");
- $event.find(".time").css({"backgroundColor": "#25B002", "border": "1px solid #888"});
- }
- },
- date: MyDate(),
- dateFormat: "j.n",
- timeFormat: "G:i",
- scrollToHourMillis: 500,
- use24Hour: true,
- readonly: true,
- showHeader: false,
- hourLine: true,
- shortDays: t("shortDays", room.config.language),
- longDays: t("longDays", room.config.language),
- buttons: false,
- timeSeparator: " " + t("to", room.config.language) + " ",
- startOnFirstDayOfWeek: false,
- displayFreeBusys: true,
- defaultFreeBusy: {free: false}
- });
- }
-
- /**
- * Generates the Calendar Div, depending on it's width
- * @param width width of the Calendar Div
- * @param room Room Object
- */
+ };
+ rooms[roomData.id] = room;
+ return room;
+ }
+
+ /**
+ * inilizes the Calendar for an room
+ * @param percent Percentages of how mucht width the Calendar div should get (only used in mode 1)
+ * @param daysToShow How many days the calendar should show
+ * @param room Room Object
+ */
+ function setUpCalendar(percent, daysToShow, room) {
+ generateCalendarDiv(percent, room);
+ room.$.calendar.weekCalendar({
+ timeslotsPerHour: 1,
+ timeslotHeight: 30,
+ daysToShow: daysToShow,
+ height: function () {
+ var height = $(window).height();
+ if (roomIds.length === 4) {
+ height /= 2;
+ }
- function generateCalendarDiv(width, room) {
- var div = document.createElement("div");
- div.id = "calendar_" + room.id;
- div.className = "calendar";
- if (room.config.vertical && room.config.mode === 1) {
- width = 100 + "%";
- $(div).css('float', "none");
- }
- div.style.width = width;
- //document.body.appendChild(div);
- $("#room_" + room.id).append(div);
-
- }
-
- const OT_DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
- const OT_KEYS = ['HourOpen', 'HourClose', 'MinutesOpen', 'MinutesClose'];
-
- /**
- * sets the opening Time in the calendar plugin and saves it in the room object
- * @param room Room Object
- */
-
- function SetOpeningTimes(room) {
- var opening = 24;
- var close = 0;
- var i;
- if (room.rawOpeningTimes && typeof(room.rawOpeningTimes) === 'object') {
- // TODO: wtf! we have three(!) formats for storing the opening times (DB, API, now this one) - WHY!?
- var parsedOpenings = room.rawOpeningTimes;
- room.state = null;
- room.openingTimesCalendar = [];
- room.openingTimes = [];
- for (i = 0; i < OT_DAYS.length; ++i) {
- room.openingTimes.push(filterOpeningTimesDay(parsedOpenings[OT_DAYS[i]]));
+ height -= room.$.header.height() - 5;
+ if (room.config.mode === 1 && room.config.vertical) {
+ height *= (room.config.scale / 100);
}
- delete room.rawOpeningTimes;
- }
- if (!room.openingTimes) {
- scaleCalendar(room);
- return;
- }
- if (room.config.mode === 3) {
- // Calendar is not displayed, don't need to do additional work
- return;
- }
- var now = MyDate();
- for (i = 0; i < 7; i++) {
- var tmp = room.openingTimes[i];
- for (var d = 0; d < tmp.length; d++) {
- var day = getNextDayOfWeek(now, i);
- if (room.openingTimesCalendar) {
- room.openingTimesCalendar.push({
- "start": new Date(day.getFullYear(), day.getMonth(), day.getDate(),
- tmp[d]['HourOpen'], tmp[d]['MinutesOpen']),
- "end": new Date(day.getFullYear(), day.getMonth(),
- day.getDate(), tmp[d]['HourClose'], tmp[d]['MinutesClose']),
- "free": true
- });
- }
- if (tmp[d]['HourOpen'] < opening) {
- opening = tmp[d]['HourOpen'];
- }
- if (tmp[d]['HourClose'] >= close) {
- close = tmp[d]['HourClose'];
- if (tmp[d]['MinutesClose'] !== 0) {
- close++;
- }
- }
+ return height;
+ },
+ eventRender: function (calEvent, $event) {
+ if (calEvent.end.getTime() < MyDate().getTime()) {
+ $event.css("backgroundColor", "#aaa");
+ $event.find(".time").css({"backgroundColor": "#999", "border": "1px solid #888"});
+ } else if (calEvent.end.getTime() > MyDate().getTime() && calEvent.start.getTime() < MyDate().getTime()) {
+ $event.css("backgroundColor", "#25B002");
+ $event.find(".time").css({"backgroundColor": "#25B002", "border": "1px solid #888"});
}
- }
- if (opening === 24 && close === 0) {
- opening = 0;
- close = 24;
- }
- room.openTimes = close - opening;
- $('#calendar_' + room.id).weekCalendar("option", "businessHours", {
- start: opening,
- end: close,
- limitDisplay: true
- });
+ },
+ date: MyDate(),
+ dateFormat: "j.n",
+ timeFormat: "G:i",
+ scrollToHourMillis: 500,
+ use24Hour: true,
+ readonly: true,
+ showHeader: false,
+ hourLine: true,
+ shortDays: t("shortDays", room.config.language),
+ longDays: t("longDays", room.config.language),
+ buttons: false,
+ timeSeparator: " " + t("to", room.config.language) + " ",
+ startOnFirstDayOfWeek: false,
+ displayFreeBusys: true,
+ defaultFreeBusy: {free: false}
+ });
+ }
+
+ /**
+ * Generates the Calendar Div, depending on it's width
+ * @param width width of the Calendar Div
+ * @param room Room Object
+ */
+
+ function generateCalendarDiv(width, room) {
+ var $cal = $('<div>').prop('id', 'calendar_' + room.id).addClass('calendar');
+ if (room.config.vertical && room.config.mode === 1) {
+ width = 100 + "%";
+ $cal.css('float', "none");
+ }
+ $cal.width(width);
+ room.$.container.append($cal);
+ room.$.calendar = $cal;
+ }
+
+ const OT_DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+ const OT_KEYS = ['HourOpen', 'HourClose', 'MinutesOpen', 'MinutesClose'];
+
+ /**
+ * sets the opening Time in the calendar plugin and saves it in the room object
+ * @param room Room Object
+ */
+
+ function SetOpeningTimes(room) {
+ var opening = 24;
+ var close = 0;
+ var i;
+ if (room.rawOpeningTimes && typeof(room.rawOpeningTimes) === 'object') {
+ // TODO: wtf! we have three(!) formats for storing the opening times (DB, API, now this one) - WHY!?
+ var parsedOpenings = room.rawOpeningTimes;
+ room.state = null;
+ room.openingTimesCalendar = [];
+ room.openingTimes = [];
+ for (i = 0; i < OT_DAYS.length; ++i) {
+ room.openingTimes.push(filterOpeningTimesDay(parsedOpenings[OT_DAYS[i]]));
+ }
+ delete room.rawOpeningTimes;
+ }
+ if (!room.openingTimes) {
scaleCalendar(room);
- }
-
- /**
- * Filter out invalid opening time entries from given array,
- * also make sure all the values are of type number (int)
- *
- * @param {Array} arr
- * @return {Array} list of valid opening times
- */
- function filterOpeningTimesDay(arr) {
- if (!arr || arr.constructor !== Array) return [];
- return arr.map(function (el) {
- if (!el || typeof el !== 'object') return null;
- for (var i = 0; i < OT_KEYS.length; ++i) {
- el[OT_KEYS[i]] = toInt(el[OT_KEYS[i]]);
- if (isNaN(el[OT_KEYS[i]])) return null;
+ return;
+ }
+ if (room.config.mode === 3) {
+ // Calendar is not displayed, don't need to do additional work
+ return;
+ }
+ var now = MyDate();
+ for (i = 0; i < 7; i++) {
+ var tmp = room.openingTimes[i];
+ for (var d = 0; d < tmp.length; d++) {
+ var day = getNextDayOfWeek(now, i);
+ if (room.openingTimesCalendar) {
+ room.openingTimesCalendar.push({
+ "start": new Date(day.getFullYear(), day.getMonth(), day.getDate(),
+ tmp[d]['HourOpen'], tmp[d]['MinutesOpen']),
+ "end": new Date(day.getFullYear(), day.getMonth(),
+ day.getDate(), tmp[d]['HourClose'], tmp[d]['MinutesClose']),
+ "free": true
+ });
}
- return el;
- }).filter(function (el) {
- if (!el) return false;
- if (el.HourOpen < 0 || el.HourOpen > 23) return false;
- if (el.HourClose < 0 || el.HourClose > 23) return false;
- if (el.HourClose < el.HourOpen) return false;
- if (el.MinutesOpen < 0 || el.MinutesOpen > 59) return false;
- if (el.MinutesClose < 0 || el.MinutesClose > 59) return false;
- if (el.HourOpen === el.HourClose && el.MinutesClose < el.MinutesOpen) return false;
- return true;
- });
- }
-
- /**
- * querys the Calendar data
- * @param ids ID'S of rooms to query as string, for e.g.: "5,17,8" or "5"
- */
- function queryCalendars() {
- if (!panelUuid) return;
- var url = "../../../api.php?do=locationinfo&get=calendar&uuid=" + panelUuid;
- $.ajax({
- url: url,
- dataType: 'json',
- cache: false,
- timeout: 30000,
- success: function (result) {
- if (result && result.constructor === Array) {
- var l = result.length;
- for (var i = 0; i < l; i++) {
- updateCalendar(result[i].calendar, rooms[result[i].id]);
- }
- }
- }, error: function () {
- // Retry in 5 minutes (300 seconds)
- lastCalendarUpdate = MyDate().getTime() + globalConfig.calupdate + 300000;
+ if (tmp[d]['HourOpen'] < opening) {
+ opening = tmp[d]['HourOpen'];
}
- });
- }
-
- const SEVEN_DAYS = 7 * 86400 * 1000;
-
- /**
- * applays new calendar data to the calendar plugin and also saves it to the room object
- * @param {Array} json Calendar data
- * @param room Room Object
- */
- function updateCalendar(json, room) {
- if (!room) {
- console.log("Error: No room for calendar data");
- return;
- }
- if (!json || json.constructor !== Array) {
- console.log("Error: Calendar data was empty or malformed.");
- return;
- }
- var now = MyDate().getTime();
- json = json.filter(function (el) {
- if (!el.title || !el.start || !el.end) return false;
- var s = new Date(el.start).getTime();
- var e = new Date(el.end).getTime();
- if (isNaN(s) || isNaN(e) || Math.abs(s - now) > SEVEN_DAYS || Math.abs(e - now) > SEVEN_DAYS) return false;
- return true;
- });
- if (json.length === 0) {
- console.log('Notice: Calendar has no current events for ' + room.name);
- }
- try {
- room.timetable = json;
- if (room.config.mode !== 3) {
- // TODO: Check if they're the same
- var cal = $('#calendar_' + room.id);
- cal.weekCalendar('option', 'data', {events: json});
- cal.weekCalendar("refresh");
- cal.weekCalendar("option", "defaultFreeBusy", {free: false});
- cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
+ if (tmp[d]['HourClose'] >= close) {
+ close = tmp[d]['HourClose'];
+ if (tmp[d]['MinutesClose'] !== 0) {
+ close++;
+ }
}
- room.state = null;
- UpdateRoomHeader(room);
- } catch (e) {
- console.log("Error: Couldnt add calendar data");
- console.log(e);
}
}
-
- /**
- * scales calendar, called once on create and on window resize
- * @param room Room Object
- */
- function scaleCalendar(room) {
- if (room.config.mode === 3) {
- return;
- }
- var cal = $('#calendar_' + room.id);
- var columnWidth = document.getElementById("calendar_" + room.id).getElementsByClassName("wc-day-1")[0].clientWidth;
-
- if (room.config.scaledaysauto) {
- var result = (cal.weekCalendar("option", "daysToShow") * columnWidth) / 100;
- result = parseInt(Math.min(Math.max(Math.abs(result), 1), 7));
- if (result !== cal.weekCalendar("option", "daysToShow")) {
- cal.weekCalendar("option", "daysToShow", result);
+ if (opening === 24 && close === 0) {
+ opening = 0;
+ close = 24;
+ }
+ room.openTimes = close - opening;
+ room.$.calendar.weekCalendar("option", "businessHours", {
+ start: opening,
+ end: close,
+ limitDisplay: true
+ });
+ scaleCalendar(room);
+ }
+
+ /**
+ * Filter out invalid opening time entries from given array,
+ * also make sure all the values are of type number (int)
+ *
+ * @param {Array} arr
+ * @return {Array} list of valid opening times
+ */
+ function filterOpeningTimesDay(arr) {
+ if (!arr || arr.constructor !== Array) return [];
+ return arr.map(function (el) {
+ if (!el || typeof el !== 'object') return null;
+ for (var i = 0; i < OT_KEYS.length; ++i) {
+ el[OT_KEYS[i]] = toInt(el[OT_KEYS[i]]);
+ if (isNaN(el[OT_KEYS[i]])) return null;
+ }
+ return el;
+ }).filter(function (el) {
+ if (!el) return false;
+ if (el.HourOpen < 0 || el.HourOpen > 23) return false;
+ if (el.HourClose < 0 || el.HourClose > 23) return false;
+ if (el.HourClose < el.HourOpen) return false;
+ if (el.MinutesOpen < 0 || el.MinutesOpen > 59) return false;
+ if (el.MinutesClose < 0 || el.MinutesClose > 59) return false;
+ if (el.HourOpen === el.HourClose && el.MinutesClose < el.MinutesOpen) return false;
+ return true;
+ });
+ }
+
+ /**
+ * querys the Calendar data
+ */
+ function queryCalendars() {
+ if (!panelUuid) return;
+ var url = "../../../api.php?do=locationinfo&get=calendar&uuid=" + panelUuid;
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ cache: false,
+ timeout: 30000,
+ success: function (result) {
+ if (result && result.constructor === Array) {
+ var l = result.length;
+ for (var i = 0; i < l; i++) {
+ updateCalendar(result[i].calendar, rooms[result[i].id]);
+ }
}
+ }, error: function () {
+ // Retry in 5 minutes (300 seconds)
+ lastCalendarUpdate = MyDate().getTime() + globalConfig.calupdate + 300000;
}
- if (((!room.config.scaledaysauto) || cal.weekCalendar("option", "daysToShow") === 1) && columnWidth < 85) {
- cal.weekCalendar("option", "useShortDayNames", true);
- } else {
- cal.weekCalendar("option", "useShortDayNames", false);
- }
- var clientHeight = $(window).height();
- if (roomIds.length === 4) {
- clientHeight = clientHeight / 2;
- }
-
- clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight
- - document.getElementsByClassName("wc-time-column-header")[0].clientHeight - 2;
-
- if (room.config.mode === 1 && room.config.vertical) {
-
- clientHeight = clientHeight * (room.config.scale / 100);
- clientHeight -= 22;
- }
- clientHeight -= 6;
- var height = clientHeight / (room.openTimes * cal.weekCalendar("option", "timeslotsPerHour"));
-
-
- if (height < 30) {
- height = 30;
- }
- // Scale calendar font
- if (height > 120) {
- cal.weekCalendar("option", "textSize", 28);
- }
- else if (height > 100) {
- cal.weekCalendar("option", "textSize", 24);
- } else if (height > 80) {
- cal.weekCalendar("option", "textSize", 22);
- } else if (height > 70) {
- cal.weekCalendar("option", "textSize", 20);
- } else if (height > 60) {
- cal.weekCalendar("option", "textSize", 14);
- } else {
- cal.weekCalendar("option", "textSize", 13);
- }
- cal.weekCalendar("option", "timeslotHeight", height);
- if (room.timetable) {
- cal.weekCalendar("option", "data", {events: room.timetable});
- cal.weekCalendar('refresh');
- }
- if (room.openingTimesCalendar) {
+ });
+ }
+
+ const SEVEN_DAYS = 7 * 86400 * 1000;
+
+ /**
+ * applays new calendar data to the calendar plugin and also saves it to the room object
+ * @param {Array} json Calendar data
+ * @param room Room Object
+ */
+ function updateCalendar(json, room) {
+ if (!room) {
+ console.log("Error: No room for calendar data");
+ return;
+ }
+ if (!json || json.constructor !== Array) {
+ console.log("Error: Calendar data was empty or malformed.");
+ return;
+ }
+ var now = MyDate().getTime();
+ json = json.filter(function (el) {
+ if (!el.title || !el.start || !el.end) return false;
+ var s = new Date(el.start).getTime();
+ var e = new Date(el.end).getTime();
+ return !(isNaN(s) || isNaN(e) || Math.abs(s - now) > SEVEN_DAYS || Math.abs(e - now) > SEVEN_DAYS);
+ });
+ if (json.length === 0) {
+ console.log('Notice: Calendar has no current events for ' + room.name);
+ }
+ try {
+ room.timetable = json;
+ if (room.config.mode !== 3) {
+ // TODO: Check if they're the same
+ var cal = room.$.calendar;
+ cal.weekCalendar('option', 'data', {events: json});
+ cal.weekCalendar("refresh");
+ cal.weekCalendar("option", "defaultFreeBusy", {free: false});
cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
}
- cal.weekCalendar("resizeCalendar");
- cal.weekCalendar("scrollToHour");
-
- }
-
- /**
- * used for countdown
- * computes the time difference between 2 Date objects
- * @param {Date} a
- * @param {Date} b
- * @param room Room Object
- * @returns time string
- */
- function GetTimeDiferenceAsString(a, b, room) {
- if (!a || !b) {
- return "";
- }
- var milliseconds = a.getTime() - b.getTime();
- var seconds = Math.floor((milliseconds / 1000) % 60);
- milliseconds -= seconds * 1000;
- var minutes = Math.floor((milliseconds / (1000 * 60)) % 60);
- milliseconds -= minutes * 1000 * 60;
- var hours = Math.floor((milliseconds / (1000 * 60 * 60)) % 24);
-
- var days = Math.floor((milliseconds / (1000 * 60 * 60 * 24)) % 31);
- if (seconds < 10) {
- seconds = "0" + seconds;
- }
- if (minutes < 10) {
- minutes = "0" + minutes;
- }
- if (days !== 0) {
- // dont show?
- return "";
- }
- if (room.config.eco) {
- return hours + ":" + minutes;
- }
- return hours + ":" + minutes + ":" + seconds;
- }
-
- /**
- * returns next closing time of a given room
- * @param room
- * @returns Date Object of next closing
- */
- function GetNextClosing(room) {
- var now = MyDate();
- var day = now.getDay();
- var bestdate = false;
- for (var a = 0; a < 7; a++) {
- var tmp = room.openingTimes[(day + a) % 7];
- if (!tmp) continue;
- for (var i = 0; i < tmp.length; i++) {
- var closeDate = getNextDayOfWeek(now, (day + a) % 7);
- closeDate.setHours(tmp[i].HourClose);
- closeDate.setMinutes(tmp[i].MinutesClose);
- closeDate.setSeconds(0);
- if (closeDate > now) {
- if (!IsOpen(new Date(closeDate.getTime() + 1800000), room)) {
- if (!bestdate || bestdate > closeDate) {
- bestdate = closeDate;
- }
+ room.state = null;
+ UpdateRoomHeader(room);
+ } catch (e) {
+ console.log("Error: Couldnt add calendar data");
+ console.log(e);
+ }
+ }
+
+ /**
+ * scales calendar, called once on create and on window resize
+ * @param room Room Object
+ */
+ function scaleCalendar(room) {
+ if (room.config.mode === 3) {
+ return;
+ }
+ var $cal = room.$.calendar;
+ if (!$cal.is(':visible')) return;
+ room.resizeCalendar = false;
+ var columnWidth = $cal.find(".wc-day-1").width();
+
+ if (room.config.scaledaysauto) {
+ var result = ($cal.weekCalendar("option", "daysToShow") * columnWidth) / 100;
+ result = parseInt(Math.min(Math.max(Math.abs(result), 1), 7));
+ if (result !== $cal.weekCalendar("option", "daysToShow")) {
+ $cal.weekCalendar("option", "daysToShow", result);
+ }
+ }
+ if (((!room.config.scaledaysauto) || $cal.weekCalendar("option", "daysToShow") === 1) && columnWidth < 85) {
+ $cal.weekCalendar("option", "useShortDayNames", true);
+ } else {
+ $cal.weekCalendar("option", "useShortDayNames", false);
+ }
+ var clientHeight = $(window).height();
+ if (roomIds.length === 4) {
+ clientHeight = clientHeight / 2;
+ }
+
+ clientHeight = clientHeight - room.$.header.height()
+ - room.$.calendar.find(".wc-time-column-header").height() - 2;
+
+ if (room.config.mode === 1 && room.config.vertical) {
+
+ clientHeight = clientHeight * (room.config.scale / 100);
+ clientHeight -= 22;
+ }
+ clientHeight -= 6;
+ var height = clientHeight / (room.openTimes * $cal.weekCalendar("option", "timeslotsPerHour"));
+
+
+ if (height < 30) {
+ height = 30;
+ }
+ // Scale calendar font
+ if (height > 120) {
+ $cal.weekCalendar("option", "textSize", 28);
+ }
+ else if (height > 100) {
+ $cal.weekCalendar("option", "textSize", 24);
+ } else if (height > 80) {
+ $cal.weekCalendar("option", "textSize", 22);
+ } else if (height > 70) {
+ $cal.weekCalendar("option", "textSize", 20);
+ } else if (height > 60) {
+ $cal.weekCalendar("option", "textSize", 14);
+ } else {
+ $cal.weekCalendar("option", "textSize", 13);
+ }
+ $cal.weekCalendar("option", "timeslotHeight", height);
+ if (room.timetable) {
+ $cal.weekCalendar("option", "data", {events: room.timetable});
+ $cal.weekCalendar('refresh');
+ }
+ if (room.openingTimesCalendar) {
+ $cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
+ }
+ $cal.weekCalendar("resizeCalendar");
+ $cal.weekCalendar("scrollToHour");
+
+ }
+
+ /**
+ * used for countdown
+ * computes the time difference between 2 Date objects
+ * @param {Date} a
+ * @param {Date} b
+ * @param room Room Object
+ * @returns time string
+ */
+ function GetTimeDiferenceAsString(a, b, room) {
+ if (!a || !b) {
+ return "";
+ }
+ var milliseconds = a.getTime() - b.getTime();
+ var seconds = Math.floor((milliseconds / 1000) % 60);
+ milliseconds -= seconds * 1000;
+ var minutes = Math.floor((milliseconds / (1000 * 60)) % 60);
+ milliseconds -= minutes * 1000 * 60;
+ var hours = Math.floor((milliseconds / (1000 * 60 * 60)) % 24);
+
+ var days = Math.floor((milliseconds / (1000 * 60 * 60 * 24)) % 31);
+ if (seconds < 10) {
+ seconds = "0" + seconds;
+ }
+ if (minutes < 10) {
+ minutes = "0" + minutes;
+ }
+ if (days !== 0) {
+ // dont show?
+ return "";
+ }
+ if (room.config.eco) {
+ return hours + ":" + minutes;
+ }
+ return hours + ":" + minutes + ":" + seconds;
+ }
+
+ /**
+ * returns next closing time of a given room
+ * @param room
+ * @returns Date Object of next closing
+ */
+ function GetNextClosing(room) {
+ var now = MyDate();
+ var day = now.getDay();
+ var bestdate = false;
+ for (var a = 0; a < 7; a++) {
+ var tmp = room.openingTimes[(day + a) % 7];
+ if (!tmp) continue;
+ for (var i = 0; i < tmp.length; i++) {
+ var closeDate = getNextDayOfWeek(now, (day + a) % 7);
+ closeDate.setHours(tmp[i].HourClose);
+ closeDate.setMinutes(tmp[i].MinutesClose);
+ closeDate.setSeconds(0);
+ if (closeDate > now) {
+ if (!IsOpen(new Date(closeDate.getTime() + 1800000), room)) {
+ if (!bestdate || bestdate > closeDate) {
+ bestdate = closeDate;
}
}
}
- if (bestdate) return bestdate;
}
- return null;
+ if (bestdate) return bestdate;
+ }
+ return null;
+ }
+
+
+ /**
+ * checks if a room is on a given date/time open
+ * @param date Date Object
+ * @param room Room object
+ * @returns bool for open or not
+ */
+ function IsOpen(date, room) {
+ if (!room.openingTimes) return false;
+ var tmp = room.openingTimes[date.getDay()];
+ if (!tmp) return false;
+ var openDate = new Date(date.getTime());
+ var closeDate = new Date(date.getTime());
+ for (var i = 0; i < tmp.length; i++) {
+ openDate.setHours(tmp[i].HourOpen);
+ openDate.setMinutes(tmp[i].MinutesOpen);
+ closeDate.setHours(tmp[i].HourClose);
+ closeDate.setMinutes(tmp[i].MinutesClose);
+ if (openDate < date && closeDate > date) {
+ return true;
+ }
}
+ return false;
+ }
- /**
- * checks if a room is on a given date/time open
- * @param date Date Object
- * @param room Room object
- * @returns bool for open or not
- */
- function IsOpen(date, room) {
- if (!room.openingTimes) return false;
- var tmp = room.openingTimes[date.getDay()];
- if (!tmp) return false;
- var openDate = new Date(date.getTime());
- var closeDate = new Date(date.getTime());
+ /**
+ * Retruns next Opening
+ * @param room Room Object
+ * @returns bestdate Date Object of next opening
+ */
+ function GetNextOpening(room) {
+ if (!room.openingTimes) return null;
+ var now = MyDate();
+ var day = now.getDay();
+ var bestdate = false;
+ for (var dow = 0; dow < 7; dow++) {
+ var tmp = room.openingTimes[(day + dow) % 7];
+ if (!tmp) continue;
for (var i = 0; i < tmp.length; i++) {
+ var openDate = getNextDayOfWeek(now, (day + dow) % 7);
openDate.setHours(tmp[i].HourOpen);
openDate.setMinutes(tmp[i].MinutesOpen);
- closeDate.setHours(tmp[i].HourClose);
- closeDate.setMinutes(tmp[i].MinutesClose);
- if (openDate < date && closeDate > date) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
- * Retruns next Opening
- * @param room Room Object
- * @returns bestdate Date Object of next opening
- */
- function GetNextOpening(room) {
- if (!room.openingTimes) return null;
- var now = MyDate();
- var day = now.getDay();
- var bestdate = false;
- for (var dow = 0; dow < 7; dow++) {
- var tmp = room.openingTimes[(day + dow) % 7];
- if (!tmp) continue;
- for (var i = 0; i < tmp.length; i++) {
- var openDate = getNextDayOfWeek(now, (day + dow) % 7);
- openDate.setHours(tmp[i].HourOpen);
- openDate.setMinutes(tmp[i].MinutesOpen);
- if (openDate > now) {
- if (!IsOpen(new Date(openDate.getTime() - 1800000), room)) {
- if (!bestdate || bestdate > openDate) {
- bestdate = openDate;
- }
+ if (openDate > now) {
+ if (!IsOpen(new Date(openDate.getTime() - 1800000), room)) {
+ if (!bestdate || bestdate > openDate) {
+ bestdate = openDate;
}
}
}
- if (bestdate) return bestdate;
}
- return null;
+ if (bestdate) return bestdate;
+ }
+ return null;
+ }
+
+
+ /**
+ * Sets the free PCs number in the right corner and updates the sqare color acordingly
+ * @param room Room
+ * @param seats Number of free PC's in the room
+ */
+ function SetFreeSeats(room, seats) {
+ room.$.seatsCounter.text(seats >= 0 ? seats : '');
+ if (seats > 0) {
+ room.$.seatsBackground.css('background-color', '#00dd10');
+ } else if (seats === -1) {
+ room.$.seatsBackground.css('background-color', 'red');
+ } else {
+ room.$.seatsBackground.css('background-color', 'red');
+ }
+ }
+
+ /**
+ * Updates the Header of an Room
+ * @param room Room Object
+ */
+ function UpdateRoomHeader(room) {
+ var tmp = room.getState();
+ var same = (tmp === room.lastHeaderState);
+ if (!same) {
+ room.lastHeaderState = tmp;
+ }
+ var newText = false, newTime = false;
+ var seats = room.freePcs;
+ if (tmp.state === 'closed' || tmp.state === 'CalendarEvent' || tmp.state === 'Free') {
+ newTime = GetTimeDiferenceAsString(tmp.end, MyDate(), room);
+ } else if (!same) {
+ newTime = '';
+ }
+ if (tmp.state === "closed") {
+ if (!same) newText = t("closed", globalConfig.language);
+ } else if (tmp.state === "CalendarEvent") {
+ if (!same) newText = tmp.title;
+ seats = -1;
+ } else if (tmp.state === "Free") {
+ if (!same) newText = t("free", room.config.language);
+ } else if (tmp.state === "FreeNoEnd") {
+ if (!same) newText = t("free", room.config.language);
+ }
+ if (newText !== false) {
+ room.$.currentEvent.text(newText);
+ }
+ if (newTime !== false) {
+ room.$.currentRemain.text(newTime);
+ }
+ if (room.lastFreeSeats !== seats) {
+ SetFreeSeats(room, room.freePcs);
+ room.lastFreeSeats = seats;
+ }
+ }
+
+ /**
+ * computes state of a room, states are:
+ * closed, FreeNoEnd, Free, CalendarEvent.
+ * @param room Object
+ */
+ function ComputeCurrentState(room) {
+ if (!IsOpen(MyDate(), room)) {
+ room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};
+
+ return;
+ }
+ var closing = GetNextClosing(room);
+
+ var event = getNextEvent(room.timetable);
+
+ // no event and no closing
+ if (!closing && !event) {
+ room.state = {state: "FreeNoEnd", end: "", title: "", next: ""};
+ return;
+ }
+
+ // no event so closing is next
+ if (!event) {
+ room.state = {state: "Free", end: closing, title: "", next: "closing"};
+ return;
+ }
+
+ // event is at the moment
+ if ((!closing || event.start.getTime() < closing.getTime()) && event.start.getTime() < MyDate()) {
+ room.state = {
+ state: "CalendarEvent",
+ end: event.end,
+ title: event.title,
+ next: ""
+ };
+ return;
}
-
- /**
- * Sets the free PCs number in the right corner and updates the sqare color acordingly
- * @param id Room id
- * @param seats Number of free PC's in the room
- */
- function SetFreeSeats(id, seats) {
- if (seats > 0) {
- $("#freeSeatsHeader_" + id).text(seats);
- $("#square_" + id).css('background-color', '#00dd10');
- } else if (seats === -1) {
- $("#freeSeatsHeader_" + id).text("");
- $("#square_" + id).css('background-color', 'red');
- } else {
- $("#freeSeatsHeader_" + id).text("0");
- $("#square_" + id).css('background-color', 'red');
- }
+ // no closing so event is next
+ if (!closing) {
+ room.state = {state: "Free", end: event.start, title: "", next: "event"};
+ return;
}
- /**
- * Updates the Header of an Room
- * @param room Room Object
- */
- function UpdateRoomHeader(room) {
- var tmp = room.getState();
- if (tmp.state === "closed") {
- $("#courseHeading_" + room.id).text(t("closed", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, MyDate(), room));
- SetFreeSeats(room.id, room.freePcs);
- } else if (tmp.state === "CalendarEvent") {
- $("#courseHeading_" + room.id).text(tmp.title);
- SetFreeSeats(room.id, -1);
- } else if (tmp.state === "Free") {
- $("#courseHeading_" + room.id).text(t("free", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, MyDate(), room));
- SetFreeSeats(room.id, room.freePcs);
- } else if (tmp.state === "FreeNoEnd") {
- $("#courseHeading_" + room.id).text(t("free", room.config.language));
- SetFreeSeats(room.id, room.freePcs);
- }
+ // event sooner then closing
+ if (event.start.getTime() < closing) {
+ room.state = {state: "Free", end: event.start, title: "", next: "event"};
+ } else {
+ room.state = {state: "Free", end: closing, title: "", next: "closing"};
}
- /**
- * computes state of a room, states are:
- * closed, FreeNoEnd, Free, CalendarEvent.
- * @param room Object
- */
- function ComputeCurrentState(room) {
- if (!IsOpen(MyDate(), room)) {
- room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};
-
- return;
- }
- var closing = GetNextClosing(room);
+ }
- var event = getNextEvent(room.timetable);
- // no event and no closing
- if (!closing && !event) {
- room.state = {state: "FreeNoEnd", end: "", title: "", next: ""};
- return;
+ /**
+ * returns next event from a given json of events
+ * @param calEvents Json which contains the calendar data.
+ * @returns event next Carlendar Event
+ */
+ function getNextEvent(calEvents) {
+ if (!calEvents) return null;
+ if (calEvents.constructor !== Array) {
+ console.log('getNextEvent called with something not array: ' + typeof(calEvents));
+ return null;
+ }
+ var event;
+ var now = MyDate();
+ for (var i = 0; i < calEvents.length; i++) {
+ //event is now active
+ if (calEvents[i].start.getTime() < now.getTime() && calEvents[i].end.getTime() > now.getTime()) {
+ return calEvents[i];
}
-
- // no event so closing is next
+ //first element to consider
if (!event) {
- room.state = {state: "Free", end: closing, title: "", next: "closing"};
- return;
+ if (calEvents[i].start.getTime() > now.getTime()) {
+ event = calEvents[i];
+ }
+ } else if (calEvents[i].start.getTime() > now.getTime() && event.start.getTime() > calEvents[i].start.getTime()) {
+ event = calEvents[i];
}
+ }
+ return event;
+ }
- // event is at the moment
- if ((!closing || event.start.getTime() < closing.getTime()) && event.start.getTime() < MyDate()) {
- room.state = {state: "CalendarEvent", end: event.end, title: event.title, next: ""};
- return;
- }
+ /**
+ * Skip to next upcoming day matching the given day of week.
+ */
+ function getNextDayOfWeek(date, dayOfWeek) {
+ var resultDate = new Date(date.getTime());
+ resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);
+ return resultDate;
+ }
+ /*
+ /========================================== Room Layout =============================================
+ */
- // no closing so event is next
- if (!closing) {
- room.state = {state: "Free", end: event.start, title: "", next: "event"};
- return;
- }
- // event sooner then closing
- if (event.start.getTime() < closing) {
- room.state = {state: "Free", end: event.start, title: "", next: "event"};
- } else {
- room.state = {state: "Free", end: closing, title: "", next: "closing"};
- }
+ var picSizeX = 3.8;
+ var picSizeY = 3;
+ /**
+ * Generates the RoomLayout Div
+ * @param width The width the RoomLayout should have (in percent).
+ * @param room Room Object
+ */
+ function generateRoomLayoutDiv(width, room) {
+ if ((room.config.vertical && room.config.mode === 1) || (room.config.mode === 3) || (room.config.mode === 4)) {
+ width = 100 + "%";
}
+ var $div = $('<div>').prop('id', 'roomLayout_' + room.id).addClass("room-layout").css('width', width);
+ if (room.config.mode === 4) {
+ $div.hide();
+ }
+ room.$.container.append($div);
+ room.$.layout = $div;
+ }
- /**
- * returns next event from a given json of events
- * @param calEvents Json which contains the calendar data.
- * @returns event next Carlendar Event
- */
- function getNextEvent(calEvents) {
- if (!calEvents) return null;
- if (calEvents.constructor !== Array) {
- console.log('getNextEvent called with something not array: ' + typeof(calEvents));
- return null;
- }
- var event;
- var now = MyDate();
- for (var i = 0; i < calEvents.length; i++) {
- //event is now active
- if (calEvents[i].start.getTime() < now.getTime() && calEvents[i].end.getTime() > now.getTime()) {
- return calEvents[i];
- }
- //first element to consider
- if (!event) {
- if (calEvents[i].start.getTime() > now.getTime()) {
- event = calEvents[i];
- }
- } else if (calEvents[i].start.getTime() > now.getTime() && event.start.getTime() > calEvents[i].start.getTime()) {
- event = calEvents[i];
- }
- }
- return event;
- }
-
- /**
- * Skip to next upcoming day matching the given day of week.
- */
- function getNextDayOfWeek(date, dayOfWeek) {
- var resultDate = new Date(date.getTime());
- resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);
- return resultDate;
- }
- /*
- /========================================== Room Layout =============================================
- */
-
-
- var picSizeX = 3.8;
- var picSizeY = 3;
-
- /**
- * Generates the RoomLayout Div
- * @param width The width the RoomLayout should have (in percent).
- * @param room Room Object
- */
- function generateRoomLayoutDiv(width, room) {
- var div = document.createElement("div");
- div.id = "roomLayout_" + room.id;
- div.className = "roomLayoutDesign";
- if ((room.config.vertical && room.config.mode === 1) || (room.config.mode === 3) || (room.config.mode === 4)) {
- width = 100 + "%";
- }
-
- div.style.width = width;
- if (room.config.mode === 4) {
- div.style.display = "none";
- }
- //document.body.appendChild(div);
- $("#room_" + room.id).append(div);
-
+ /**
+ * Main function for generating the Room Layout
+ * @param room Room Object
+ */
+ function initRoomLayout(room) {
+ var maxX = false, maxY = false;
+ var minX = false, minY = false;
+ var xDifference, yDifference;
+ var x, y;
+ generateRoomLayoutDiv((100 - room.config.scale) + "%", room);
+ var layout = room.layout;
+ if (layout === null || !layout.length) {
+ return;
}
- /**
- * Main function for generating the Room Layout
- * @param layout Layout Json
- * @param room Room Object
- */
- function initRoomLayout(room) {
- var maxX = false, maxY = false;
- var minX = false, minY = false;
- var xDifference, yDifference;
- var x, y;
+ rotateRoom(room.config.rotation, layout);
- generateRoomLayoutDiv((100 - globalConfig.scale) + "%", room);
- var layout = room.layout;
- if (layout === null || !layout.length) {
- return;
+ for (var i = 0; i < layout.length; i++) {
+ x = layout[i].x = parseInt(layout[i].x);
+ y = layout[i].y = parseInt(layout[i].y);
+ if (isNaN(x) || isNaN(y)) continue;
+ if (minX === false || x < minX) {
+ minX = x;
}
-
- rotateRoom(globalConfig.rotation, layout);
-
- for (var i = 0; i < layout.length; i++) {
- x = layout[i].x = parseInt(layout[i].x);
- y = layout[i].y = parseInt(layout[i].y);
- if (isNaN(x) || isNaN(y)) continue;
- if (minX === false || x < minX) {
- minX = x;
- }
- if (minY === false || y < minY) {
- minY = y;
- }
- if (maxX === false || x > maxX) {
- maxX = x;
- }
- if (maxY === false || y > maxY) {
- maxY = y;
- }
+ if (minY === false || y < minY) {
+ minY = y;
+ }
+ if (maxX === false || x > maxX) {
+ maxX = x;
+ }
+ if (maxY === false || y > maxY) {
+ maxY = y;
}
-
- xDifference = maxX - minX;
- yDifference = maxY - minY;
-
- room.xDifference = xDifference;
- room.yDifference = yDifference;
- room.minX = minX;
- room.minY = minY;
- room.maxX = maxX;
- room.maxY = maxY;
-
- generateOffsetAndScale(room);
- setUpRoom(room, layout);
- scaleRoom(room);
- UpdatePc(layout, room);
-
}
- /**
- * Computes offsets and scaling's for the RoomLayout
- * @param room Room Object
- */
- function generateOffsetAndScale(room) {
+ xDifference = maxX - minX;
+ yDifference = maxY - minY;
- var clientHeight = $(window).height();
- if (roomIds.length === 4) {
- clientHeight = clientHeight / 2;
- }
+ room.xDifference = xDifference;
+ room.yDifference = yDifference;
+ room.minX = minX;
+ room.minY = minY;
+ room.maxX = maxX;
+ room.maxY = maxY;
- clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight - 5;
+ setUpRoom(room, layout);
+ scaleRoom(room);
+ UpdatePc(layout, room);
- if (roomIds.length > 1) {
- clientHeight -= 5;
- }
- if (globalConfig.vertical && globalConfig.mode === 1) {
- clientHeight = clientHeight * (1 - (globalConfig.scale / 100));
- }
- var roomLayout = document.getElementById('roomLayout_' + room.id);
-
- var clientWidth = roomLayout.clientWidth;
- //roomLayout.style.height = clientHeight + "px";
+ }
- var scaleX;
- if (room.xDifference !== 0) {
- scaleX = clientWidth / room.xDifference;
- } else {
- scaleX = clientWidth;
- }
- var scaleY;
- if (room.yDifference !== 0) {
- scaleY = clientHeight / room.yDifference;
- } else {
- scaleY = clientHeight;
- }
- var scaleYs = (clientHeight - (picSizeY * scaleY)) / room.yDifference;
- var scaleXs = (clientWidth - (picSizeX * scaleX)) / room.xDifference;
- if (scaleYs <= 0) {
- scaleYs = 9999;
- }
- if (scaleXs <= 0) {
- scaleXs = 9999;
- }
+ /**
+ * Computes offsets and scaling's for the RoomLayout
+ * @param room Room Object
+ */
+ function generateOffsetAndScale(room) {
- room.scale = Math.min(scaleYs, scaleY, scaleXs, scaleX, (clientHeight * 0.9) / picSizeY, (clientWidth * 0.9) / picSizeX);
- room.xOffset = 0 - room.minX;
- room.yOffset = 0 - room.minY;
- room.xOffset += ((1 / 2 * (clientWidth - (((room.maxX + room.xOffset) * room.scale) + picSizeX * room.scale))) / room.scale);
- room.yOffset += ((1 / 2 * (clientHeight - (((room.maxY + room.yOffset) * room.scale) + picSizeY * room.scale))) / room.scale);
+ var clientHeight = $(window).height();
+ if (roomIds.length === 4) {
+ clientHeight /= 2;
}
-
- /**
- * adds images for each pc to Room Layout
- * @param room Room Object
- * @param layout Layout json
- */
- function setUpRoom(room, layout) {
- for (var i = 0; i < layout.length; i++) {
- if (!isNaN(layout[i].y) && !isNaN(layout[i].x)) {
- var text = "<div class= 'PCImgDiv' id ='layout_PC_div_" + room.id + "_" + layout[i].id + "'>" +
-
- "<div class= 'OverlayDiv' id ='layout_PC_overlay_" + room.id + "_" + layout[i].id + "'>" +
- "</div>" +
- "<img class= 'pcImg' id ='layout_PC_" + room.id + "_" + layout[i].id + "'> </img>" +
- "</div>";
-
- $('#roomLayout_' + room.id).append(text);
- if (layout[i].overlay && layout[i].overlay.constructor === Array) {
- for (var a = 0; a < layout[i].overlay.length; a++) {
- addOverlay($('#layout_PC_overlay_' + room.id + "_" + layout[i].id), layout[i].overlay[a]);
- }
- }
- }
- }
+ clientHeight -= room.$.header.height() - 5;
+
+ if (roomIds.length > 1) {
+ clientHeight -= 5;
+ }
+ if (room.config.vertical && room.config.mode === 1) {
+ clientHeight *= (1 - (room.config.scale / 100));
}
- /**
- * Adds an overlay to an div(here the PC's shown in the RoomLayout).
- * @param object Object where the overlay should be added
- * @param overlayName name of the overlay (image name without ending)
- */
- function addOverlay(object, overlayName) {
- var a = [".svg", ".png", "jpg"];
- var imgname;
- for (var i = 0; i < a.length; a++) {
- if (imageExists("img/overlay/" + overlayName + a[i])) {
- imgname = "img/overlay/" + overlayName + a[i];
- break;
- }
+ var clientWidth = room.$.layout.width();
- }
- if (!imgname) return; // No image found on server, do nothing
- var $text = $("<img>");
- $text.addClass('overlay').attr('src', imgname).addClass("overlay-" + overlayName);
- object.append($text);
+ var scaleX;
+ if (room.xDifference !== 0) {
+ scaleX = clientWidth / room.xDifference;
+ } else {
+ scaleX = clientWidth;
+ }
+ var scaleY;
+ if (room.yDifference !== 0) {
+ scaleY = clientHeight / room.yDifference;
+ } else {
+ scaleY = clientHeight;
+ }
+ var scaleYs = (clientHeight - (picSizeY * scaleY)) / room.yDifference;
+ var scaleXs = (clientWidth - (picSizeX * scaleX)) / room.xDifference;
+ if (scaleYs <= 0) {
+ scaleYs = 9999;
+ }
+ if (scaleXs <= 0) {
+ scaleXs = 9999;
}
+ room.scale = Math.min(scaleYs, scaleY, scaleXs, scaleX, (clientHeight * 0.9) / picSizeY, (clientWidth * 0.9) / picSizeX);
+ room.xOffset = 0 - room.minX;
+ room.yOffset = 0 - room.minY;
+ room.xOffset += ((1 / 2 * (clientWidth - (((room.maxX + room.xOffset) * room.scale) + picSizeX * room.scale))) / room.scale);
+ room.yOffset += ((1 / 2 * (clientHeight - (((room.maxY + room.yOffset) * room.scale) + picSizeY * room.scale))) / room.scale);
+ }
- var imgExists = {};
- /**
- * checks if images exists on the webserver(chaches it also)
- * @param image_url Path to the image
- */
- function imageExists(image_url) {
- if (!imgExists.hasOwnProperty(image_url)) {
- var http = new XMLHttpRequest();
- http.open('HEAD', image_url, false);
- http.send();
- imgExists[image_url] = http.status === 200;
- }
- return imgExists[image_url];
-
- }
-
- /**
- * Querys Pc states
- */
- function queryRooms() {
- $.ajax({
- url: "../../../api.php?do=locationinfo&get=machines&uuid=" + panelUuid,
- dataType: 'json',
- cache: false,
- timeout: 30000,
- success: function (result) {
- if (!result || result.constructor !== Array) {
- console.log('Warning: get=machines didnt return array');
- return;
- }
- for (var i = 0; i < result.length; i++) {
- UpdatePc(result[i].machines, rooms[result[i].id]);
- }
- }
- })
- }
-
- /**
- * Updates the PC's (images) in the room layout. Also Updates how many pc's are free.
- * @param update Update Json from query for one(!) room
- * @param room Room object
- */
- function UpdatePc(update, room) {
- if (!room) {
- console.log('Got room update for unknown room, ignored.');
- return;
- }
- if (!update || update.constructor !== Array) {
- console.log('Update data is not array for room ' + room.name);
- console.log(update);
- return;
- }
- var freePcs = 0;
- for (var i = 0; i < update.length; i++) {
- var $imgobj = $("#layout_PC_" + room.id + "_" + update[i].id);
-
- var img;
- var color;
- // Pc free
- if (update[i].pcState === "IDLE") {
- img = "img/pc_free";
- color = 'green';
- freePcs++;
- // Pc in use
- } else if (update[i].pcState === "OCCUPIED") {
- img = "img/pc_used";
- color = 'red';
- // PC off
- } else if (update[i].pcState === "OFF") {
- img = "img/pc_off";
- color = 'black';
- freePcs++;
- // Must be defect
- } else {
- img = "img/pc_defect";
- color = 'black';
- }
+ /**
+ * adds images for each pc to Room Layout
+ * @param room Room Object
+ * @param layout Layout json
+ */
+ function setUpRoom(room, layout) {
+ for (var i = 0; i < layout.length; i++) {
+ if (!isNaN(layout[i].y) && !isNaN(layout[i].x)) {
+ var $img = $('<img>').prop('id', "pc-img_" + room.id + "_" + layout[i].id).addClass('pc-img');
+ var $overlays = $('<div>').addClass('pc-overlay-container');
+ layout[i].$div = $('<div>').addClass('pc-container');
+ layout[i].$div.append($overlays).append($img);
+ room.$.layout.append(layout[i].$div);
- if (supportSvg) {
- if (room.config.eco) {
- img = img + "_eink";
+ if (layout[i].overlay && layout[i].overlay.constructor === Array) {
+ for (var a = 0; a < layout[i].overlay.length; a++) {
+ addOverlay($overlays, layout[i].overlay[a]);
}
- $imgobj.attr('src', img + ".svg");
- } else {
- $imgobj.css('background-color', color);
}
-
}
- room.freePcs = freePcs;
- UpdateRoomHeader(room);
}
-
- /**
- * Adjust pc coordinate depending on room rotation
- * @param r Rotation, from 0 - 3 (int)
- * @param layout Layout json
- */
- function rotateRoom(r, layout) {
- for (var z = 0; z < r; z++) {
- for (var i = 0; i < layout.length; i++) {
- var x = parseInt(layout[i].x);
- var y = parseInt(layout[i].y);
- layout[i].x = y;
- layout[i].y = -x;
+ }
+
+ /**
+ * Generate overlay with given image name.
+ * @param $container container to put overlay into
+ * @param overlayName name of the overlay (image name without ending)
+ */
+ function addOverlay($container, overlayName) {
+ var a = [".svg", ".png", ".jpg"];
+ var imgname;
+ for (var i = 0; i < a.length; a++) {
+ if (imageExists("img/overlay/" + overlayName + a[i])) {
+ imgname = "img/overlay/" + overlayName + a[i];
+ break;
+ }
+
+ }
+ if (!imgname) return null; // No image found on server, do nothing
+ var $overlay = $("<img>");
+ $overlay.addClass('overlay').attr('src', imgname).addClass("overlay-" + overlayName);
+ $container.append($overlay);
+ }
+
+
+ var imgExists = {};
+
+ /**
+ * checks if images exists on the web server.
+ * result will be cached after fist call.
+ *
+ * @param {String} image_url URL of image to check
+ * @return {Boolean} true iff image exists
+ */
+ function imageExists(image_url) {
+ if (!imgExists.hasOwnProperty(image_url)) {
+ var http = new XMLHttpRequest();
+ http.open('HEAD', image_url, false);
+ http.send();
+ imgExists[image_url] = http.status === 200;
+ }
+ return imgExists[image_url];
+
+ }
+
+ /**
+ * Queries Pc states
+ */
+ function queryRooms() {
+ $.ajax({
+ url: "../../../api.php?do=locationinfo&get=machines&uuid=" + panelUuid,
+ dataType: 'json',
+ cache: false,
+ timeout: 30000,
+ success: function (result) {
+ if (!result || result.constructor !== Array) {
+ console.log('Warning: get=machines didnt return array');
+ return;
}
- }
- }
-
- /**
- * Positions the computer images in the roomLayout div accoring to ther potion and div size
- * @param room Room object
- */
- function scaleRoom(room) {
- for (var i = 0; i < room.layout.length; i++) {
- if (!isNaN(room.layout[i].y) && !isNaN(room.layout[i].x)) {
- var tmp = document.getElementById("layout_PC_div_" + room.id + "_" + room.layout[i].id);
- if (tmp) {
- tmp.style.width = (picSizeX * room.scale);
- tmp.setAttribute("style", "width:" + (picSizeX * room.scale) + "px");
- tmp.style.height = (picSizeY * room.scale) + "px";
- tmp.style.left = ((room.layout[i].x + room.xOffset) * room.scale) + "px";
- tmp.style.top = ((room.layout[i].y + room.yOffset) * room.scale) + "px";
- }
+ for (var i = 0; i < result.length; i++) {
+ UpdatePc(result[i].machines, rooms[result[i].id]);
}
}
- }
-
- /*
- /========================================== Misc =============================================
- */
- var resizeTimeout = false;
-
- // called when browser window changes size
- // scales calendar and room layout acordingly
-
- $(window).resize(function () {
- if (resizeTimeout) clearTimeout(resizeTimeout);
- resizeTimeout = setTimeout(function () {
- resizeTimeout = false;
- for (var property in rooms) {
- rooms[property].resized = true;
- if (rooms[property].config.mode !== null) {
- if (rooms[property].config.mode !== 3) {
- scaleCalendar(rooms[property]);
- }
- if (rooms[property].config.mode !== 2) {
- generateOffsetAndScale(rooms[property]);
- scaleRoom(rooms[property]);
- }
- }
- }
- SetProgressBarSpeed();
- }, 200);
- });
-
-
- /**
- * returns parameter value from the url
- * @param sParam
- * @returns value for given parameter
- */
- var getUrlParameter = function getUrlParameter(sParam) {
- var sPageURL = decodeURIComponent(window.location.search.substring(1)),
- sURLVariables = sPageURL.split('&'),
- sParameterName,
- i;
-
- for (i = 0; i < sURLVariables.length; i++) {
- sParameterName = sURLVariables[i].split('=', 2);
-
- if (sParameterName[0] === sParam) {
- if (sParameterName.length === 1) return true;
- return sParameterName[1];
- }
+ })
+ }
+
+ /**
+ * Updates the PC's (images) in the room layout. Also Updates how many pc's are free.
+ * @param update Update Json from query for one(!) room
+ * @param room Room object
+ */
+ function UpdatePc(update, room) {
+ if (!room) {
+ console.log('Got room update for unknown room, ignored.');
+ return;
+ }
+ if (!update || update.constructor !== Array) {
+ console.log('Update data is not array for room ' + room.name);
+ console.log(update);
+ return;
+ }
+ var freePcs = 0;
+ for (var i = 0; i < update.length; i++) {
+ var $imgobj = $("#pc-img_" + room.id + "_" + update[i].id);
+
+ var img;
+ var color;
+ // Pc free
+ if (update[i].pcState === "IDLE") {
+ img = "img/pc_free";
+ color = 'green';
+ freePcs++;
+ // Pc in use
+ } else if (update[i].pcState === "OCCUPIED") {
+ img = "img/pc_used";
+ color = 'red';
+ // PC off
+ } else if (update[i].pcState === "OFF") {
+ img = "img/pc_off";
+ color = 'black';
+ freePcs++;
+ // Must be defect
+ } else {
+ img = "img/pc_defect";
+ color = 'black';
}
- return false;
- };
- /**
- * Function for translation
- * @param toTranslate key which we wan't to translate
- * @param lang languages in which should be translated
- * @returns r translated string
- */
- function t(toTranslate, lang) {
-
- var r;
- if (!lang || !translation[lang] || !translation[lang][toTranslate]) {
- r = translation['en'][toTranslate] || 'missing';
+ if (supportSvg) {
+ if (globalConfig.eco) {
+ img = img + "_eink";
+ }
+ $imgobj.attr('src', img + ".svg");
} else {
- r = translation[lang][toTranslate];
+ $imgobj.css('background-color', color);
}
- return r;
- }
-
-
- /**
- * Used in Mode 4, switches given room from Timetable to Roomlayout and vice versa
- * @param room
- */
- function switchLayouts() {
- for (var roomKey in rooms) {
- var room = rooms[roomKey];
- if (room.config.mode !== 4) continue;
- var car = document.getElementById("calendar_" + room.id);
- var roomLayout = document.getElementById("roomLayout_" + room.id);
-
- if (car.style.display === "none") {
- roomLayout.style.display = "none";
- car.style.display = "block";
- if (room.resized) {
- scaleCalendar(room);
- room.resized = false;
- }
- } else {
- car.style.display = "none";
- roomLayout.style.display = "block";
- if (room.resized) {
- generateOffsetAndScale(room);
- scaleRoom(room);
- room.resized = false;
- }
- }
+
+ }
+ room.freePcs = freePcs;
+ UpdateRoomHeader(room);
+ }
+
+ /**
+ * Adjust pc coordinate depending on room rotation
+ * @param r Rotation, from 0 - 3 (int)
+ * @param layout Layout json
+ */
+ function rotateRoom(r, layout) {
+ for (var z = 0; z < r; z++) {
+ for (var i = 0; i < layout.length; i++) {
+ var x = parseInt(layout[i].x);
+ var y = parseInt(layout[i].y);
+ layout[i].x = y;
+ layout[i].y = -x;
+ }
+ }
+ }
+
+ /**
+ * Positions the computer images in the roomLayout div according to their position and div size
+ * @param room Room object
+ */
+ function scaleRoom(room) {
+ if (!room.$.layout.is(':visible')) return;
+ room.resizeRoom = false;
+ generateOffsetAndScale(room);
+ for (var i = 0; i < room.layout.length; i++) {
+ var pcWidth = (picSizeX * room.scale) + "px";
+ var pcHeight = (picSizeY * room.scale) + "px";
+ if (room.layout[i].$div && !isNaN(room.layout[i].y) && !isNaN(room.layout[i].x)) {
+ room.layout[i].$div.css({
+ width: pcWidth,
+ height: pcHeight,
+ top: ((room.layout[i].y + room.yOffset) * room.scale) + "px",
+ left: ((room.layout[i].x + room.xOffset) * room.scale) + "px"
+ });
}
- lastSwitchTime = MyDate().getTime();
}
+ }
- var $pbar = false;
- var pbarTimer = false;
- const PX_PER_SEC_TARGET = 10;
+ /*
+ /========================================== Misc =============================================
+ */
+ var resizeTimeout = false;
- /**
- * adds a progressbar (id) used in mode 4
- */
- function generateProgressBar() {
- if ($pbar) return;
- $pbar = $('<div id="progressBar" class="progressbar">');
- $('body').append($pbar);
- SetProgressBarSpeed()
- }
+ // called when browser window changes size
+ // scales calendar and room layout accordingly
- function SetProgressBarSpeed() {
- if (!$pbar || !globalConfig.switchtime) return;
- if (pbarTimer) clearInterval(pbarTimer);
- var pxPerMSec = $('body').width() / globalConfig.switchtime;
- var interval = Math.max(1 / (pxPerMSec / PX_PER_SEC_TARGET), 100);
- pbarTimer = setInterval(function () {
- var width = ((MyDate().getTime() - lastSwitchTime) / globalConfig.switchtime) * 100;
- if (width < 0) width = 0;
- if (width >= 100) {
- width = 100;
- switchLayouts();
- }
- $pbar.width(width + '%');
- }, interval);
+ $(window).resize(function () {
+ if (resizeTimeout !== false) clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(function () {
+ resizeTimeout = false;
+ for (var property in rooms) {
+ rooms[property].resizeCalendar = true;
+ rooms[property].resizeRoom = true;
+ scaleCalendar(rooms[property]);
+ scaleRoom(rooms[property]);
+ }
+ SetProgressBarSpeed();
+ }, 200);
+ });
+
+
+ /**
+ * returns parameter value from the url
+ * @param sParam
+ * @returns boolean|string for given parameter
+ */
+ function getUrlParameter(sParam) {
+ var sPageURL = decodeURIComponent(window.location.search.substring(1)),
+ sURLVariables = sPageURL.split('&'),
+ sParameterName,
+ i;
+
+ for (i = 0; i < sURLVariables.length; i++) {
+ sParameterName = sURLVariables[i].split('=', 2);
+
+ if (sParameterName[0] === sParam) {
+ if (sParameterName.length === 1) return true;
+ return sParameterName[1];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Function for translation
+ * @param toTranslate key which we wan't to translate
+ * @param lang languages in which should be translated
+ * @returns r translated string
+ */
+ function t(toTranslate, lang) {
+
+ var r;
+ if (!lang || !translation[lang] || !translation[lang][toTranslate]) {
+ r = translation['en'][toTranslate] || 'missing';
+ } else {
+ r = translation[lang][toTranslate];
+ }
+ return r;
+ }
+
+ function resizeIfRequired(room) {
+ if (room.resizeCalendar) {
+ scaleCalendar(room);
}
-
- function toInt(str) {
- var t = typeof str;
- if (t === 'number') return str | 0;
- if (t === 'string') return parseInt(str.replace(/^0+([^0])/, '$1'));
- return NaN;
+ if (room.resizeRoom) {
+ scaleRoom(room);
}
+ }
- </script>
-</head>
-<body>
-</body>
+
+ /**
+ * Used in Mode 4, switches given room from Timetable to room layout and vice versa
+ */
+ function switchLayouts() {
+ for (var roomKey in rooms) {
+ var room = rooms[roomKey];
+ if (room.config.mode !== 4) continue;
+ if (room.$.layout.is(':visible')) {
+ room.$.layout.hide();
+ room.$.calendar.show();
+ } else {
+ room.$.layout.show();
+ room.$.calendar.hide();
+ }
+ resizeIfRequired(room);
+ }
+ lastSwitchTime = MyDate().getTime();
+ }
+
+ var $pbar = false;
+ var pbarTimer = false;
+ const PX_PER_SEC_TARGET = 10;
+
+ /**
+ * adds a progressbar (id) used in mode 4
+ */
+ function generateProgressBar() {
+ if ($pbar) return;
+ $pbar = $('<div id="progressBar" class="progressbar">');
+ $('body').append($pbar);
+ SetProgressBarSpeed();
+ }
+
+ function SetProgressBarSpeed() {
+ if (!$pbar || !globalConfig.switchtime) return;
+ if (pbarTimer) clearInterval(pbarTimer);
+ var interval = 1000;
+ if (!globalConfig.eco) {
+ var pxPerMSec = $('body').width() / globalConfig.switchtime;
+ interval = Math.max(1 / (pxPerMSec / PX_PER_SEC_TARGET), 100);
+ }
+ pbarTimer = setInterval(function () {
+ var width = ((MyDate().getTime() - lastSwitchTime) / globalConfig.switchtime) * 100;
+ if (width < 0) width = 0;
+ if (width >= 100) {
+ width = 100;
+ switchLayouts();
+ }
+ $pbar.width(width + '%');
+ }, interval);
+ }
+
+ function toInt(str) {
+ var t = typeof str;
+ if (t === 'number') return str | 0;
+ if (t === 'string') return parseInt(str.replace(/^0+([^0])/, '$1'));
+ return NaN;
+ }
+
+</script>
</html>