1 | <?php |
||||
2 | /* |
||||
3 | Copyright (C) 2014-2015 Universitätsbibliothek Mannheim |
||||
4 | See file LICENSE for license details. |
||||
5 | |||||
6 | Authors: Alexander Wagner, Stefan Weil, Dennis Müller |
||||
7 | |||||
8 | References: |
||||
9 | |||||
10 | File upload (general) |
||||
11 | |||||
12 | * http://www.php.net/manual/en/features.file-upload.post-method.php |
||||
13 | |||||
14 | File upload with dropzone |
||||
15 | |||||
16 | * http://www.dropzonejs.com/ |
||||
17 | * http://www.startutorial.com/articles/view/how-to-build-a-file-upload-form-using-dropzonejs-and-php |
||||
18 | * http://maxoffsky.com/code-blog/howto-ajax-multiple-file-upload-in-laravel/ |
||||
19 | |||||
20 | Websockets: |
||||
21 | |||||
22 | * https://en.wikipedia.org/wiki/Server-sent_events |
||||
23 | * https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications |
||||
24 | * http://code.google.com/p/phpwebsocket/ |
||||
25 | * http://dharman.eu/?menu=phpWebSocketsTutorial |
||||
26 | |||||
27 | Keyboard input |
||||
28 | |||||
29 | * http://jsfiddle.net/angusgrant/E3tE6/ |
||||
30 | * http://stackoverflow.com/questions/3181648/how-can-i-handle-arrowkeys-and-greater-than-in-a-javascript-function-which |
||||
31 | * http://stackoverflow.com/questions/5597060/detecting-arrow-key-presses-in-javascript |
||||
32 | * http://www.quirksmode.org/js/keys.html |
||||
33 | |||||
34 | Key symbols |
||||
35 | |||||
36 | * http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm |
||||
37 | |||||
38 | * wmctrl, suckless-tools (lsw, sprop, wmname, ...) |
||||
39 | |||||
40 | * display.im6, evince |
||||
41 | |||||
42 | Authorization |
||||
43 | |||||
44 | * http://aktuell.de.selfhtml.org/artikel/php/loginsystem/ |
||||
45 | |||||
46 | Overlays |
||||
47 | |||||
48 | * http://answers.oreilly.com/topic/1823-adding-a-page-overlay-in-javascript/ |
||||
49 | |||||
50 | */ |
||||
51 | |||||
52 | session_start(); |
||||
53 | if (isset($_REQUEST['monitor'])) { |
||||
54 | $monitor = $_REQUEST['monitor']; |
||||
55 | $_SESSION['monitor'] = $monitor; |
||||
56 | } elseif (!isset($_SESSION['monitor'])) { |
||||
57 | $_SESSION['monitor'] = '???'; |
||||
58 | } |
||||
59 | $_SESSION['referer'] = 'index.php'; |
||||
60 | require_once('auth.php'); |
||||
61 | |||||
62 | // Connect to database and get configuration constants. |
||||
63 | require_once('DBConnector.class.php'); |
||||
64 | $dbcon = new palma\DBConnector(); |
||||
65 | |||||
66 | // Support localisation. |
||||
67 | require_once('i12n.php'); |
||||
68 | |||||
69 | $user = false; |
||||
70 | if (isset($_SESSION['username'])) { |
||||
71 | # PHP session based authorization. |
||||
72 | $username = $_SESSION['username']; |
||||
73 | $address = $_SESSION['address']; |
||||
74 | $user = "$username@$address"; |
||||
75 | } elseif (isset($_SERVER['PHP_AUTH_USER'])) { |
||||
76 | # .htaccess basic authorization. |
||||
77 | $user = $_SERVER['PHP_AUTH_USER']; |
||||
78 | } |
||||
79 | |||||
80 | require_once('globals.php'); |
||||
81 | /* |
||||
82 | * file paths for vnc downloads |
||||
83 | */ |
||||
84 | $winvnc = CONFIG_START_URL . "theme/" . CONFIG_THEME . "/winvnc-palma.exe"; |
||||
85 | $macvnc = "https://www.bib.uni-mannheim.de/palma/VineServer.dmg"; |
||||
86 | $linuxsh = CONFIG_START_URL . "theme/" . CONFIG_THEME . "/x11.sh"; |
||||
87 | |||||
88 | /* |
||||
89 | * contact form elements |
||||
90 | * might be sourced out and included |
||||
91 | */ |
||||
92 | if (isset($_POST['submit'])) { |
||||
93 | $to = "[email protected]"; |
||||
94 | $to = "[email protected]"; |
||||
95 | $from = $_POST['email']; |
||||
96 | $name = $_POST['name']; |
||||
97 | $subject = "Feedback for PalMA"; |
||||
98 | $message = $name . " wrote the following:" . "\n\n" . $_POST['message']; |
||||
99 | |||||
100 | $headers = "From:" . $from; |
||||
101 | mail($to, $subject, $message, $headers); |
||||
102 | echo "Mail Sent. Thank you for your feedback " . $name . ", we will get in touch with you shortly."; |
||||
103 | } |
||||
104 | |||||
105 | ?> |
||||
106 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" |
||||
107 | "http://www.w3.org/TR/html4/strict.dtd"> |
||||
108 | |||||
109 | <html> |
||||
110 | |||||
111 | <head> |
||||
112 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||||
113 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
114 | <title>PalMA</title> |
||||
115 | |||||
116 | <link rel="icon" href="theme/<?=CONFIG_THEME?>/favicon.ico" type="image/x-icon"> |
||||
117 | <link rel="stylesheet" href="font-awesome/css/font-awesome.min.css"> |
||||
118 | <link rel="stylesheet" href="pure-min.css"> |
||||
119 | <link rel="stylesheet" href="palma.css" type="text/css"> |
||||
120 | |||||
121 | <script type="text/javascript" src="jquery.min.js"></script> |
||||
122 | |||||
123 | <script type="text/javascript" src="dropzone.js"></script> |
||||
124 | |||||
125 | <script type="text/javascript"> |
||||
126 | |||||
127 | // Screen section which responds to keyboard input. |
||||
128 | var focus_section = '1'; |
||||
129 | |||||
130 | function sendToNuc(command) { |
||||
131 | var xmlHttp = new XMLHttpRequest(); |
||||
132 | if (!xmlHttp) { |
||||
133 | // TODO |
||||
134 | alert('XMLHttpRequest failed!'); |
||||
135 | return; |
||||
136 | } |
||||
137 | var url = 'control.php?' + command; |
||||
138 | var response = ""; |
||||
139 | xmlHttp.open("get", url, true); |
||||
140 | xmlHttp.onreadystatechange = function () { |
||||
141 | if (xmlHttp.readyState == 1) { |
||||
142 | // Server connection established (IE only). |
||||
143 | } else if (xmlHttp.readyState == 2) { |
||||
144 | // Data transferred to server. |
||||
145 | } else if (xmlHttp.readyState == 3) { |
||||
146 | // Server is answering. |
||||
147 | } else if (xmlHttp.readyState == 4) { |
||||
148 | // Received all data from server. |
||||
149 | return xmlHttp.responseText; |
||||
150 | } else { |
||||
151 | alert("Got xmlHttp.readyState " + xmlHttp.readyState); |
||||
152 | } |
||||
153 | }; |
||||
154 | xmlHttp.send(null); |
||||
155 | //~ alert("sendToNuc " + url); |
||||
156 | } |
||||
157 | |||||
158 | function keyControl(number, image, controlClass, key, handler, disabled, title) { |
||||
159 | // "number" refers to the slected screensection |
||||
160 | |||||
161 | var keyHandler = getHandlerCommand(handler, key); |
||||
162 | if ( (keyHandler == "") || (keyHandler == null) ) { |
||||
163 | keyHandler = "default"; |
||||
164 | } |
||||
165 | |||||
166 | var button = document.createElement('button'); |
||||
167 | var icon = document.createElement('i'); |
||||
168 | if (!disabled) { |
||||
169 | icon.setAttribute('class', image); |
||||
170 | button.appendChild(icon); |
||||
171 | button.setAttribute('class', controlClass); |
||||
172 | button.setAttribute('onmousedown', |
||||
173 | 'sendToNuc("window=' + number + '&keydown=' + encodeURIComponent(keyHandler) + '")'); |
||||
174 | button.setAttribute('onmouseup', |
||||
175 | 'sendToNuc("window=' + number + '&keyup=' + encodeURIComponent(keyHandler) + '")'); |
||||
176 | button.setAttribute('title', title); |
||||
177 | } else { |
||||
178 | icon.setAttribute('class', image + " unavailable"); |
||||
179 | button.appendChild(icon); |
||||
180 | button.setAttribute("class", "unavailable"); |
||||
181 | button.setAttribute('title', title + " " + "<?=__('not available')?>"); |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
182 | } |
||||
183 | return button; |
||||
184 | } |
||||
185 | |||||
186 | function downloadFile(screensection) { |
||||
187 | |||||
188 | // wrong path if copied to /home/directory |
||||
189 | // TODO: check file and path |
||||
190 | |||||
191 | var url = document.URL; |
||||
192 | var url_path = url.split("/"); |
||||
193 | |||||
194 | var file = document.getElementById("file" + screensection).innerHTML; |
||||
195 | var file = document.getElementById("file" + screensection).getAttribute("title"); |
||||
196 | |||||
197 | // Download with download.php |
||||
198 | var download = url_path[0]+"/"+url_path[1]+"/"+url_path[2]+"/"+url_path[3]+"/download.php?file="+encodeURIComponent(file); |
||||
199 | |||||
200 | var name = "Download"; |
||||
201 | |||||
202 | if(file.indexOf("www.") > -1) { |
||||
203 | window.open(file, name); |
||||
204 | } else { |
||||
205 | window.open(download, name); |
||||
206 | } |
||||
207 | } |
||||
208 | |||||
209 | function is_valid_url(url) |
||||
210 | { |
||||
211 | return url.match(/(^(ht|f)tps?:\/\/)([a-zA-Z0-9\.-])+(\.([a-zA-Z]{2,}))(\/([^\s\<\>\,\{\}\\\|\^\[\]\'])*)?$/); |
||||
212 | } |
||||
213 | |||||
214 | function urlToNuc() { |
||||
215 | |||||
216 | var url = document.getElementById('url_field').value; |
||||
217 | if (is_valid_url(url)) { |
||||
218 | // Encode special characters |
||||
219 | url = encodeURIComponent(url); |
||||
220 | sendToNuc('openURL='+url); |
||||
221 | } else { |
||||
222 | var urlfield = document.getElementById('url_field'); |
||||
223 | urlfield.setAttribute('value', '<?=__("Enter valid URL")?>'); |
||||
224 | } |
||||
225 | |||||
226 | setTimeout(function(){location.reload()}, 1000); |
||||
227 | } |
||||
228 | |||||
229 | function showLayout(layout, controls, window) { |
||||
230 | //~ console.log("Layout: " + layout); |
||||
231 | //~ for (i = 0; i < controls.length; i++) { |
||||
232 | //~ console.log("SL " + i + ": " + controls[i]); |
||||
233 | //~ } |
||||
234 | |||||
235 | document.onkeydown = function(evt) { |
||||
236 | evt = evt || window.event; |
||||
237 | var section = focus_section; |
||||
238 | var handler = controls[focus_section][0]; |
||||
239 | var keyHandler; |
||||
240 | //~ console.log("Key down: " + evt.keyCode); |
||||
241 | switch (evt.keyCode) { |
||||
242 | case 33: // page up |
||||
243 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'prior')); |
||||
244 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
245 | break; |
||||
246 | case 34: // page down |
||||
247 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'next')); |
||||
248 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
249 | break; |
||||
250 | case 35: // end |
||||
251 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'end')); |
||||
252 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
253 | break; |
||||
254 | case 36: // home |
||||
255 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'home')); |
||||
256 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
257 | break; |
||||
258 | case 37: // left |
||||
259 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'left')); |
||||
260 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
261 | break; |
||||
262 | case 38: // up |
||||
263 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'up')); |
||||
264 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
265 | break; |
||||
266 | case 39: // right |
||||
267 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'right')); |
||||
268 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
269 | break; |
||||
270 | case 40: // down |
||||
271 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'down')); |
||||
272 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
273 | break; |
||||
274 | } |
||||
275 | }; |
||||
276 | |||||
277 | document.onkeypress = function(evt) { |
||||
278 | evt = evt || window.event; |
||||
279 | //~ console.log("Key press: " + evt.keyCode); |
||||
280 | var charCode = evt.which || evt.keyCode; |
||||
281 | var charStr = String.fromCharCode(charCode); |
||||
282 | var section = focus_section; |
||||
283 | var handler = controls[focus_section][0]; |
||||
284 | var keyHandler; |
||||
285 | switch (charStr) { |
||||
286 | case "1": // select section 1 |
||||
287 | case "2": // select section 2 |
||||
288 | case "3": // select section 3 |
||||
289 | case "4": // select section 4 |
||||
290 | focus_section = charStr; |
||||
291 | break; |
||||
292 | case "+": // zoom in |
||||
293 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'zoomin')); |
||||
294 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
295 | break; |
||||
296 | case "-": // zoom out |
||||
297 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'zoomout')); |
||||
298 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||||
299 | break; |
||||
300 | } |
||||
301 | }; |
||||
302 | |||||
303 | var windowlist = document.getElementById('windowlist'); |
||||
304 | var entries = windowlist.getElementsByClassName('window_entry'); |
||||
305 | var screensection, file, status; |
||||
306 | markCurrentLayout(layout); |
||||
307 | for (var n = 0; n < window.length; n++) { |
||||
308 | screensection = window[n].section; |
||||
309 | file = window[n].file; |
||||
310 | status = window[n].state; |
||||
311 | entries[n].appendChild(addWindowControls(layout, controls, screensection, file, status)); |
||||
312 | } |
||||
313 | } |
||||
314 | |||||
315 | function markCurrentLayout(layout) { |
||||
316 | var layoutDivs = document.getElementsByClassName("screenlayout"); |
||||
317 | for (var i = 0 ; i < layoutDivs.length ; i++) { |
||||
318 | var children = layoutDivs[i].getElementsByClassName("pure-button"); |
||||
319 | for (var k = 0 ; k < children.length ; k++) { |
||||
320 | children[k].style.backgroundColor = ""; |
||||
321 | } |
||||
322 | } |
||||
323 | document.getElementById(layout).style.backgroundColor = "#990000"; |
||||
324 | } |
||||
325 | |||||
326 | function miniDisplaySelect(element) { |
||||
327 | sendToNuc('layout=' + element.id); |
||||
328 | markCurrentLayout(element.id); |
||||
329 | } |
||||
330 | |||||
331 | function getHandlerCommand(handle, task) { |
||||
332 | |||||
333 | // console.log("getHandlerCommand "+handle+" - "+task); |
||||
334 | // to deactivate buttons just add 'undefined' as keystroke |
||||
335 | |||||
336 | var handler = []; |
||||
337 | |||||
338 | handler["default"] = {}; |
||||
339 | // handler["default"]["init"] = ""; |
||||
340 | handler["default"]["up"] = "Up"; |
||||
341 | handler["default"]["down"] = "Down"; |
||||
342 | handler["default"]["left"] = "Left"; |
||||
343 | handler["default"]["right"] = "Right"; |
||||
344 | handler["default"]["next"] = "Next"; |
||||
345 | handler["default"]["prior"] = "Prior"; |
||||
346 | handler["default"]["home"] = "Home"; |
||||
347 | handler["default"]["end"] = "End"; |
||||
348 | handler["default"]["zoomin"] = "ctrl+plus"; |
||||
349 | handler["default"]["zoomout"] = "ctrl+minus"; |
||||
350 | handler["default"]["download"] = "download"; |
||||
351 | handler["default"]["counterclockwise"] = "undefined"; |
||||
352 | handler["default"]["clockwise"] = "undefined"; |
||||
353 | |||||
354 | // Handler for web pages. |
||||
355 | handler["midori"] = {}; |
||||
356 | handler["midori"]["up"] = "Up"; |
||||
357 | handler["midori"]["down"] = "Down"; |
||||
358 | handler["midori"]["left"] = "Left"; |
||||
359 | handler["midori"]["right"] = "Right"; |
||||
360 | handler["midori"]["next"] = "Next"; |
||||
361 | handler["midori"]["prior"] = "Prior"; |
||||
362 | handler["midori"]["home"] = "Home"; |
||||
363 | handler["midori"]["end"] = "End"; |
||||
364 | handler["midori"]["zoomin"] = "ctrl+plus"; |
||||
365 | handler["midori"]["zoomout"] = "ctrl+minus"; |
||||
366 | handler["midori"]["download"] = "undefined"; |
||||
367 | handler["midori"]["counterclockwise"] = "undefined"; |
||||
368 | handler["midori"]["clockwise"] = "undefined"; |
||||
369 | |||||
370 | // Handler for images. |
||||
371 | handler["feh"] = {}; |
||||
372 | handler["feh"]["up"] = "alt+Up"; |
||||
373 | handler["feh"]["down"] = "alt+Down"; |
||||
374 | handler["feh"]["left"] = "alt+Left"; |
||||
375 | handler["feh"]["right"] = "alt+Right"; |
||||
376 | handler["feh"]["next"] = "alt+Next"; |
||||
377 | handler["feh"]["prior"] = "alt+Prior"; |
||||
378 | handler["feh"]["home"] = "undefined"; |
||||
379 | handler["feh"]["end"] = "undefined"; |
||||
380 | handler["feh"]["zoomin"] = "KP_Add"; |
||||
381 | handler["feh"]["zoomout"] = "KP_Subtract"; |
||||
382 | handler["feh"]["download"] = "download"; |
||||
383 | handler["feh"]["counterclockwise"] = "less"; |
||||
384 | handler["feh"]["clockwise"] = "greater"; |
||||
385 | |||||
386 | // Controls in LibreOffice: no zoom in calc and writer, has to be activated first |
||||
387 | // by pressing <Ctrl+Shift+o> (switch view mode on/off) not implemented yet |
||||
388 | handler["libreoffice"] = {}; |
||||
389 | handler["libreoffice"]["up"] = "Up"; |
||||
390 | handler["libreoffice"]["down"] = "Down"; |
||||
391 | handler["libreoffice"]["left"] = "Left"; |
||||
392 | handler["libreoffice"]["right"] = "Right"; |
||||
393 | handler["libreoffice"]["next"] = "Next"; |
||||
394 | handler["libreoffice"]["prior"] = "Prior"; |
||||
395 | handler["libreoffice"]["home"] = "undefined"; |
||||
396 | handler["libreoffice"]["end"] = "undefined"; |
||||
397 | handler["libreoffice"]["zoomin"] = "undefined"; |
||||
398 | handler["libreoffice"]["zoomout"] = "undefined"; |
||||
399 | handler["libreoffice"]["download"] = "download"; |
||||
400 | handler["libreoffice"]["counterclockwise"] = "undefined"; |
||||
401 | handler["libreoffice"]["clockwise"] = "undefined"; |
||||
402 | |||||
403 | // Handler for MS Excel and LibreOffice Calc documents. |
||||
404 | handler["libreoffice-calc"] = {}; |
||||
405 | handler["libreoffice-calc"]["up"] = "Up"; |
||||
406 | handler["libreoffice-calc"]["down"] = "Down"; |
||||
407 | handler["libreoffice-calc"]["left"] = "Left"; |
||||
408 | handler["libreoffice-calc"]["right"] = "Right"; |
||||
409 | handler["libreoffice-calc"]["next"] = "Next"; |
||||
410 | handler["libreoffice-calc"]["prior"] = "Prior"; |
||||
411 | handler["libreoffice-calc"]["home"] = "Home"; |
||||
412 | handler["libreoffice-calc"]["end"] = "End"; |
||||
413 | handler["libreoffice-calc"]["zoomin"] = "undefined"; |
||||
414 | handler["libreoffice-calc"]["zoomout"] = "undefined"; |
||||
415 | handler["libreoffice-calc"]["download"] = "download"; |
||||
416 | handler["libreoffice-calc"]["counterclockwise"] = "undefined"; |
||||
417 | handler["libreoffice-calc"]["clockwise"] = "undefined"; |
||||
418 | |||||
419 | // Handler for MS Powerpoint and LibreOffice Impress documents. |
||||
420 | handler["libreoffice-impress"] = {}; |
||||
421 | handler["libreoffice-impress"]["up"] = "Up"; |
||||
422 | handler["libreoffice-impress"]["down"] = "Down"; |
||||
423 | handler["libreoffice-impress"]["left"] = "Left"; |
||||
424 | handler["libreoffice-impress"]["right"] = "Right"; |
||||
425 | handler["libreoffice-impress"]["next"] = "Next"; |
||||
426 | handler["libreoffice-impress"]["prior"] = "Prior"; |
||||
427 | handler["libreoffice-impress"]["home"] = "Home"; |
||||
428 | handler["libreoffice-impress"]["end"] = "End"; |
||||
429 | handler["libreoffice-impress"]["zoomin"] = "plus"; |
||||
430 | handler["libreoffice-impress"]["zoomout"] = "minus"; |
||||
431 | handler["libreoffice-impress"]["download"] = "download"; |
||||
432 | handler["libreoffice-impress"]["counterclockwise"] = "undefined"; |
||||
433 | handler["libreoffice-impress"]["clockwise"] = "undefined"; |
||||
434 | |||||
435 | // Handler for MS Word and LibreOffice Writer documents. |
||||
436 | handler["libreoffice-writer"] = {}; |
||||
437 | handler["libreoffice-writer"]["up"] = "Up"; |
||||
438 | handler["libreoffice-writer"]["down"] = "Down"; |
||||
439 | handler["libreoffice-writer"]["left"] = "Left"; |
||||
440 | handler["libreoffice-writer"]["right"] = "Right"; |
||||
441 | handler["libreoffice-writer"]["next"] = "Next"; |
||||
442 | handler["libreoffice-writer"]["prior"] = "Prior"; |
||||
443 | handler["libreoffice-writer"]["home"] = "undefined"; |
||||
444 | handler["libreoffice-writer"]["end"] = "undefined"; |
||||
445 | handler["libreoffice-writer"]["zoomin"] = "undefined"; |
||||
446 | handler["libreoffice-writer"]["zoomout"] = "undefined"; |
||||
447 | handler["libreoffice-writer"]["download"] = "download"; |
||||
448 | handler["libreoffice-writer"]["counterclockwise"] = "undefined"; |
||||
449 | handler["libreoffice-writer"]["clockwise"] = "undefined"; |
||||
450 | |||||
451 | // Handler for videos. |
||||
452 | handler["vlc"] = {}; |
||||
453 | handler["vlc"]["up"] = "undefined"; |
||||
454 | handler["vlc"]["down"] = "undefined"; |
||||
455 | handler["vlc"]["left"] = "undefined"; |
||||
456 | handler["vlc"]["right"] = "space"; |
||||
457 | handler["vlc"]["next"] = "undefined"; |
||||
458 | handler["vlc"]["prior"] = "undefined"; |
||||
459 | handler["vlc"]["home"] = "undefined"; |
||||
460 | handler["vlc"]["end"] = "undefined"; |
||||
461 | handler["vlc"]["zoomin"] = "undefined"; |
||||
462 | handler["vlc"]["zoomout"] = "undefined"; |
||||
463 | handler["vlc"]["download"] = "undefined"; |
||||
464 | handler["vlc"]["counterclockwise"] = "undefined"; |
||||
465 | handler["vlc"]["clockwise"] = "undefined"; |
||||
466 | |||||
467 | // Handler for shared desktops (VNC). |
||||
468 | handler["vnc"] = {}; |
||||
469 | handler["vnc"]["up"] = "Up"; |
||||
470 | handler["vnc"]["down"] = "Down"; |
||||
471 | handler["vnc"]["left"] = "Left"; |
||||
472 | handler["vnc"]["right"] = "Right"; |
||||
473 | handler["vnc"]["next"] = "undefined"; |
||||
474 | handler["vnc"]["prior"] = "undefined"; |
||||
475 | handler["vnc"]["home"] = "undefined"; |
||||
476 | handler["vnc"]["end"] = "undefined"; |
||||
477 | handler["vnc"]["zoomin"] = "plus"; |
||||
478 | handler["vnc"]["zoomout"] = "minus"; |
||||
479 | handler["vnc"]["download"] = "undefined"; |
||||
480 | handler["vnc"]["counterclockwise"] = "undefined"; |
||||
481 | handler["vnc"]["clockwise"] = "undefined"; |
||||
482 | |||||
483 | // Handler for PDF documents. |
||||
484 | handler["zathura"] = {}; |
||||
485 | handler["zathura"]["up"] = "Up"; |
||||
486 | handler["zathura"]["down"] = "Down"; |
||||
487 | handler["zathura"]["left"] = "Left"; |
||||
488 | handler["zathura"]["right"] = "Right"; |
||||
489 | handler["zathura"]["next"] = "Next"; |
||||
490 | handler["zathura"]["prior"] = "Prior"; |
||||
491 | handler["zathura"]["home"] = "Home"; |
||||
492 | handler["zathura"]["end"] = "End"; |
||||
493 | handler["zathura"]["zoomin"] = "plus"; |
||||
494 | handler["zathura"]["zoomout"] = "minus"; |
||||
495 | handler["zathura"]["download"] = "download"; |
||||
496 | handler["zathura"]["counterclockwise"] = "undefined"; |
||||
497 | handler["zathura"]["clockwise"] = "undefined"; |
||||
498 | |||||
499 | var send_keys = handler["default"]["up"]; |
||||
500 | |||||
501 | if (typeof(handler[handle]) !== "undefined") { |
||||
502 | send_keys = handler[handle][task]; |
||||
503 | } |
||||
504 | |||||
505 | // console.log(send_keys); |
||||
506 | |||||
507 | return send_keys; |
||||
508 | } |
||||
509 | |||||
510 | Dropzone.options.palmaDropzone = { |
||||
511 | init: function() { |
||||
512 | this.on("complete", function() { |
||||
513 | if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0) { |
||||
514 | // File finished uploading, and there aren't any left in the queue. |
||||
515 | // console.log("File(s) uploaded"); |
||||
516 | setTimeout(function() { |
||||
517 | location.reload(); |
||||
518 | }, 1); |
||||
519 | // location.reload(); // verlangt Eingabe von Enter zum wiederholten Schicken der Daten |
||||
520 | } |
||||
521 | }); |
||||
522 | } |
||||
523 | }; |
||||
524 | |||||
525 | function updateUserList(address, user) { |
||||
526 | // Update the user list on screen from the table in the database. |
||||
527 | |||||
528 | // Get the <tbody> element which contains the user entries. |
||||
529 | var list = document.getElementById('userlist'); |
||||
530 | |||||
531 | // First we remove all existing <tr> elements. |
||||
532 | while (list.firstChild) { |
||||
533 | list.removeChild(list.firstChild); |
||||
534 | } |
||||
535 | |||||
536 | if (address.length > 0) { |
||||
537 | // Add an entry for each user. Iterate over addresses: |
||||
538 | // One user may be connected several times with different devices. |
||||
539 | // We don't expect more than one user from the same device. |
||||
540 | var m; |
||||
541 | for (m = 0; m < address.length; m++) { |
||||
542 | var n; |
||||
543 | for (n = 0; n < user.length; n++) { |
||||
544 | if (address[m].userid == user[n].userid) { |
||||
545 | break; |
||||
546 | } |
||||
547 | } |
||||
548 | var device = address[m].device; |
||||
549 | var tr = document.createElement('tr'); |
||||
550 | var td = document.createElement('td'); |
||||
551 | var i = document.createElement('i'); |
||||
552 | i.setAttribute('class', 'fa fa-fw fa-' + device); |
||||
553 | td.appendChild(i); |
||||
554 | td.appendChild(document.createTextNode(user[n].name)); |
||||
555 | tr.appendChild(td); |
||||
556 | list.appendChild(tr); |
||||
557 | } |
||||
558 | } else { |
||||
559 | <?php |
||||
560 | if ($user) { |
||||
561 | ?> |
||||
562 | // All users were disconnected. |
||||
563 | alert("<?=__('You were disconnected!')?>"); |
||||
564 | window.location = 'logout.php'; |
||||
565 | <?php |
||||
566 | } else { |
||||
567 | ?> |
||||
568 | // If there is no user, we display an empty entry. |
||||
569 | var tr = document.createElement('tr'); |
||||
570 | var td = document.createElement('td'); |
||||
571 | td.appendChild(document.createTextNode("\u00a0")); |
||||
572 | tr.appendChild(td); |
||||
573 | list.appendChild(tr); |
||||
574 | <?php |
||||
575 | } |
||||
576 | ?> |
||||
577 | } |
||||
578 | } |
||||
579 | |||||
580 | |||||
581 | function addWindowPosition(layout, screensection) { |
||||
582 | var position = document.createElement("div"); |
||||
583 | position.setAttribute("class", "position " + layout); |
||||
584 | position.setAttribute('title', '<?=str_replace("'", "\\'", __("Select screen section for display"))?>'); |
||||
585 | |||||
586 | var s; |
||||
587 | var button; |
||||
588 | var icon; |
||||
589 | var br; |
||||
590 | |||||
591 | switch (layout) { |
||||
592 | case 'g1x1': |
||||
593 | s = 1; |
||||
594 | break; |
||||
595 | case 'g1x2': |
||||
596 | s = 2; |
||||
597 | break; |
||||
598 | case 'g2x1': |
||||
599 | s = 2; |
||||
600 | break; |
||||
601 | case 'g1a2': |
||||
602 | s = 3; |
||||
603 | var layout_left = document.createElement('div'); |
||||
604 | layout_left.setAttribute("class", "layout_left"); |
||||
605 | var layout_right = document.createElement('div'); |
||||
606 | layout_right.setAttribute("class", "layout_right"); |
||||
607 | break; |
||||
608 | case 'g2x2': |
||||
609 | s = 4; |
||||
610 | break; |
||||
611 | } |
||||
612 | |||||
613 | for (var n = 1; n <= s; n++) { |
||||
614 | br = ''; |
||||
615 | button = document.createElement("button"); |
||||
616 | button.setAttribute('value', n); |
||||
617 | if (n == screensection) { |
||||
618 | button.setAttribute("class", "selected"); |
||||
619 | } |
||||
620 | button.setAttribute('onclick', "sendToNuc('switchWindows=TRUE&before=" + screensection + "&after='+(this.value))"); |
||||
621 | icon = document.createElement("i"); |
||||
622 | if (s == 1) { |
||||
623 | icon.setAttribute("class", "fa fa-desktop fa-2x"); |
||||
624 | } else { |
||||
625 | icon.setAttribute("class", "fa fa-desktop fa-1x"); |
||||
626 | } |
||||
627 | button.appendChild(icon); |
||||
628 | |||||
629 | if ((layout == 'g1x2' && n == 1) || ((layout == 'g1a2' || layout == 'g2x2') && n == 2 )) { |
||||
630 | br = document.createElement("br"); |
||||
631 | } |
||||
632 | |||||
633 | if (layout == 'g1a2' && n == 1) { |
||||
634 | layout_left.appendChild(button); |
||||
635 | } else if (layout == 'g1a2' && n > 1) { |
||||
636 | layout_right.appendChild(button); |
||||
637 | if (br) { |
||||
638 | layout_right.appendChild(br); |
||||
639 | } |
||||
640 | } else { |
||||
641 | position.appendChild(button); |
||||
642 | if (br) { |
||||
643 | position.appendChild(br); |
||||
644 | } |
||||
645 | } |
||||
646 | } |
||||
647 | |||||
648 | if (layout == 'g1a2') { |
||||
649 | position.appendChild(layout_left); |
||||
650 | position.appendChild(layout_right); |
||||
651 | } |
||||
652 | return position; |
||||
653 | } |
||||
654 | |||||
655 | |||||
656 | function addWindowControls(layout, controls, screensection, file, status) { |
||||
657 | var control = controls[screensection]; |
||||
658 | if (typeof control == "undefined") { |
||||
659 | control = ["default", false, false, false, false, |
||||
660 | false, false, false, false, false, false, false]; |
||||
661 | } |
||||
662 | |||||
663 | // get handler |
||||
664 | var handler = control[0]; |
||||
665 | // up down left right zoomin zoomout home end prior next download |
||||
666 | var up = control[1]; |
||||
667 | var down = control[2]; |
||||
668 | var left = control[3]; |
||||
669 | var right = control[4]; |
||||
670 | var zoomin = control[5]; |
||||
671 | var zoomout = control[6]; |
||||
672 | var home = control[7]; |
||||
673 | var end = control[8]; |
||||
674 | var prior = control[9]; |
||||
675 | var next = control[10]; |
||||
676 | var download = control[11]; |
||||
677 | var counterclockwise = control[12]; |
||||
678 | var clockwise = control[13]; |
||||
679 | |||||
680 | var windowcontrols = document.createElement("div"); |
||||
681 | windowcontrols.setAttribute("class", "windowcontrols"); |
||||
682 | |||||
683 | var topbar = document.createElement("div"); |
||||
684 | topbar.setAttribute("class", "topbar"); |
||||
685 | var button = document.createElement('button'); |
||||
686 | button.setAttribute("class", "toggle"); |
||||
687 | icon = document.createElement('i'); |
||||
688 | if (status == 'active') { |
||||
689 | icon.setAttribute("class", "fa fa-eye"); |
||||
690 | } else { |
||||
691 | icon.setAttribute("class", "fa fa-eye-slash"); |
||||
692 | } |
||||
693 | icon.setAttribute('id', 'status_' + screensection); |
||||
694 | button.setAttribute('title', '<?=__("Toggle visibility")?>'); |
||||
695 | button.setAttribute('onclick', "sendToNuc('window=" + screensection + "&toggle=TRUE')"); |
||||
696 | button.appendChild(icon); |
||||
697 | topbar.appendChild(button); |
||||
698 | topbar.appendChild(keyControl(screensection, 'fa fa-search-plus', 'zoomin', 'zoomin', handler, !zoomin, '<?=__("Zoom in")?>')); |
||||
699 | topbar.appendChild(keyControl(screensection, 'fa fa-search-minus', 'zoomout', 'zoomout', handler, !zoomout, '<?=__("Zoom out")?>')); |
||||
700 | topbar.appendChild(keyControl(screensection, 'fa fa-rotate-left', 'counterclockwise', 'counterclockwise', handler, !counterclockwise, '<?=__("Rotate counterclockwise")?>')); |
||||
701 | topbar.appendChild(keyControl(screensection, 'fa fa-rotate-right', 'clockwise', 'clockwise', handler, !clockwise, '<?=__("Rotate clockwise")?>')); |
||||
702 | var downloadbutton = keyControl(screensection, 'fa fa-download', 'download', 'download', handler, !download, '<?=__("Download this item")?>'); |
||||
703 | downloadbutton.setAttribute('onclick', 'downloadFile(' + screensection + ')'); |
||||
704 | topbar.appendChild(downloadbutton); |
||||
705 | button = document.createElement('button'); |
||||
706 | button.setAttribute("class", "trash"); |
||||
707 | button.setAttribute('onclick', "sendToNuc('window=" + screensection + "&delete=" + file + "')"); |
||||
708 | button.setAttribute('title', '<?=__("Remove this item")?>'); |
||||
709 | icon = document.createElement('i'); |
||||
710 | icon.setAttribute("class", "fa fa-trash-o"); |
||||
711 | button.appendChild(icon); |
||||
712 | topbar.appendChild(button); |
||||
713 | |||||
714 | var movement = document.createElement("div"); |
||||
715 | movement.setAttribute("class", "movement"); |
||||
716 | |||||
717 | var jump = document.createElement("div"); |
||||
718 | jump.setAttribute("class", "jump"); |
||||
719 | jump.appendChild(keyControl(screensection, 'fa fa-angle-double-up', 'jumpbeginning', 'home', handler, !home, '<?=__("Jump to start")?>')); |
||||
720 | jump.appendChild(keyControl(screensection, 'fa fa-angle-up', 'pageback', 'prior', handler, !prior, '<?=__("Page up")?>')); |
||||
721 | jump.appendChild(keyControl(screensection, 'fa fa-angle-down', 'pageforward', 'next', handler, !next, '<?=__("Page down")?>')); |
||||
722 | jump.appendChild(keyControl(screensection, 'fa fa-angle-double-down', 'jumpend', 'end', handler, !end, '<?=__("Jump to end")?>')); |
||||
723 | |||||
724 | var arrows = document.createElement("div"); |
||||
725 | arrows.setAttribute("class", "arrows"); |
||||
726 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-up', 'arrowup', 'up', handler, !up, '<?=__("Up")?>')); |
||||
727 | arrows.appendChild(document.createElement("br")); |
||||
728 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-left', 'arrowleft', 'left', handler, !left, '<?=__("Left")?>')); |
||||
729 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-right', 'arrowright', 'right', handler, !right, '<?=__("Right")?>')); |
||||
730 | arrows.appendChild(document.createElement("br")); |
||||
731 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-down', 'arrowdown', 'down', handler, !down, '<?=__("Down")?>')); |
||||
732 | |||||
733 | movement.appendChild(jump); |
||||
734 | movement.appendChild(arrows); |
||||
735 | |||||
736 | var position = addWindowPosition(layout, screensection); |
||||
737 | |||||
738 | // Putting it all together |
||||
739 | windowcontrols.appendChild(topbar); |
||||
740 | windowcontrols.appendChild(movement); |
||||
741 | windowcontrols.appendChild(position); |
||||
742 | return windowcontrols; |
||||
743 | } |
||||
744 | |||||
745 | |||||
746 | function updateWindowList(window){ |
||||
747 | var windowlist = document.getElementById('windowlist'); |
||||
748 | // remove old entries |
||||
749 | while (windowlist.firstChild) { |
||||
750 | windowlist.removeChild(windowlist.firstChild); |
||||
751 | } |
||||
752 | |||||
753 | if (window.length == 0) { |
||||
754 | var entry = document.createElement('div'); |
||||
755 | entry.setAttribute("class", "description"); |
||||
756 | entry.appendChild(document.createTextNode('<?=__('Welcome')?>, <?=$username?>!')); |
||||
757 | entry.appendChild(document.createElement("br")); |
||||
758 | entry.appendChild(document.createTextNode('<?=__('There is no shared content yet. Click below to get started!')?>')); |
||||
759 | var addbutton = document.createElement('button'); |
||||
760 | addbutton.setAttribute("class", "splash_add pure-button"); |
||||
761 | addbutton.setAttribute("onclick", "openTab(event, 'Add')"); |
||||
762 | var addtext = (document.createTextNode('<?=__("Add")?>')); |
||||
763 | addbutton.appendChild(addtext); |
||||
764 | var addicon = document.createElement("i"); |
||||
765 | addicon.setAttribute("class", "fa fa-plus"); |
||||
766 | addbutton.appendChild(addicon); |
||||
767 | windowlist.appendChild(entry); |
||||
768 | windowlist.appendChild(addbutton); |
||||
769 | document.getElementById("closeWindows").style.display = "none"; |
||||
770 | document.getElementById("Layout").style.display = "none"; |
||||
771 | document.getElementById("controlbtn").className = "tablinks"; |
||||
772 | } else { |
||||
773 | document.getElementById("closeWindows").style.display = "inline-block"; |
||||
774 | document.getElementById("Layout").style.display = "block"; |
||||
775 | document.getElementById("controlbtn").className = "tablinks active"; |
||||
776 | // Add an entry for each window. |
||||
777 | var n; |
||||
778 | for (n = 0; n < window.length; n++) { |
||||
779 | var file = window[n].file; |
||||
780 | var handler = window[n].handler; |
||||
781 | var screensection = window[n].section; |
||||
782 | var entry = document.createElement('div'); |
||||
783 | entry.setAttribute("class", "window_entry"); |
||||
784 | var divID = 'file' + screensection; |
||||
785 | entry.setAttribute('id', divID); |
||||
786 | |||||
787 | var button = document.createElement('button'); |
||||
788 | button.setAttribute("class", "window_entry_button"); |
||||
789 | button.setAttribute('onclick', "openAccordion('" + divID + "')"); |
||||
790 | var icon = document.createElement('i'); |
||||
791 | if (handler.indexOf("midori") > -1) { |
||||
792 | icon.setAttribute("class", "fa fa-globe"); |
||||
793 | } else if (handler.indexOf("vnc") > -1) { |
||||
794 | icon.setAttribute("class", "fa fa-video-camera"); |
||||
795 | } else if (handler.indexOf("vlc") > -1) { |
||||
796 | icon.setAttribute("class", "fa fa-film"); |
||||
797 | } else if (handler.indexOf("feh") > -1) { |
||||
798 | icon.setAttribute("class", "fa fa-picture-o"); |
||||
799 | } else if (handler.indexOf("zathura") > -1) { |
||||
800 | icon.setAttribute("class", "fa fa-file-pdf-o"); |
||||
801 | } else { |
||||
802 | icon.setAttribute("class", "fa fa-file"); |
||||
803 | } |
||||
804 | button.appendChild(icon); |
||||
805 | var title = decodeURI(decodeURIComponent(file)); |
||||
806 | // display only the last part of the URL or file name. |
||||
807 | // Long names are truncated, and the truncation is indicated. |
||||
808 | if (title.substring(0, 4) == 'http') { |
||||
809 | // Remove a terminating slash from an URL. |
||||
810 | // The full URL will be shown as a tooltip. |
||||
811 | title = title.replace(/\/$/, ''); |
||||
812 | title = title.replace(/^.*\//, ''); |
||||
813 | entry.setAttribute('title', file); |
||||
814 | } else { |
||||
815 | // For files only the full base name is shown as a tooltip. |
||||
816 | var fname = file; |
||||
817 | title = title.replace(/^.*\//, ''); |
||||
818 | entry.setAttribute('title', fname); |
||||
819 | } |
||||
820 | if (title.length > 25) { |
||||
821 | title = title.substring(0, 25) + '...'; |
||||
822 | } |
||||
823 | button.appendChild(document.createTextNode(title)); |
||||
824 | var icon = document.createElement('i'); |
||||
825 | icon.setAttribute("class", "fa fa-caret-down accordion-icon"); |
||||
826 | button.appendChild(icon); |
||||
827 | entry.appendChild(button); |
||||
828 | windowlist.appendChild(entry); |
||||
829 | } |
||||
830 | } |
||||
831 | } |
||||
832 | |||||
833 | function updateControlsBySection(window) { |
||||
834 | |||||
835 | // get section and handler for each window |
||||
836 | var sectionControls = []; |
||||
837 | |||||
838 | for (n = 0; n < window.length; n++) { |
||||
839 | var win_id = window[n].win_id; |
||||
840 | var section = window[n].section; |
||||
841 | var handler = window[n].handler; |
||||
842 | |||||
843 | // alert("Section: " + section + " - Handler: " + handler); |
||||
844 | |||||
845 | if (handler.indexOf("feh") > -1) { |
||||
846 | // up down left right zoomin zoomout home end prior next download rotateleft rotateright |
||||
847 | control = ["feh", true, true, true, true, true, true, false, false, false, false, true, true, true]; |
||||
848 | } else if (handler.indexOf("libreoffice") > -1) { |
||||
849 | // Controls in LibreOffice: no zoom in calc and writer, has to be activated first |
||||
850 | // by pressing <Ctrl+Shift+o> (switch view mode on/off) not implemented yet |
||||
851 | control = ["libreoffice", true, true, true, true, false, false, false, false, true, true, true, false, false]; |
||||
852 | if (handler.indexOf("--calc") > -1) { |
||||
853 | control = ["libreoffice-calc", true, true, true, true, false, false, true, true, true, true, true, false, false]; |
||||
854 | } |
||||
855 | if (handler.indexOf("--impress") > -1) { |
||||
856 | control = ["libreoffice-impress", true, true, true, true, true, true, true, true, true, true, true, false, false]; |
||||
857 | } |
||||
858 | if (handler.indexOf("--writer") > -1) { |
||||
859 | control = ["libreoffice-writer", true, true, true, true, false, false, false, false, true, true, true, false, false]; |
||||
860 | } |
||||
861 | } else if (handler.indexOf("midori") > -1) { |
||||
862 | control = ["midori", true, true, true, true, true, true, true, true, true, true, false, false, false]; |
||||
863 | } else if (handler.indexOf("vlc") > -1) { |
||||
864 | control = ["vlc", false, false, false, true, false, false, false, false, false, false, false, false, false]; |
||||
865 | } else if (handler.indexOf("vnc") > -1) { |
||||
866 | control = ["vnc", true, true, true, true, true, true, false, false, false, false, false, false, false]; |
||||
867 | } else if (handler.indexOf("zathura") > -1) { |
||||
868 | control = ["zathura", true, true, true, true, true, true, true, true, true, true, true, false, false]; |
||||
869 | } else { |
||||
870 | control = ["undefined", false, false, false, false, false, false, false, false, false, false, false, false, false]; |
||||
871 | } |
||||
872 | |||||
873 | sectionControls[section] = control; |
||||
874 | } |
||||
875 | |||||
876 | // Fill empty sections with default values. |
||||
877 | for (i = sectionControls.length; i < 5; i++) { |
||||
878 | sectionControls[i] = ["default", |
||||
879 | false, false, false, false, |
||||
880 | false, false, false, false, |
||||
881 | false, false, false, false, false]; |
||||
882 | } |
||||
883 | |||||
884 | return sectionControls; |
||||
885 | } |
||||
886 | |||||
887 | function updateScreen() { |
||||
888 | sendToNuc('window=all&closeOrphans=true'); |
||||
889 | } |
||||
890 | |||||
891 | function clearURLField(defaultText) { |
||||
892 | var browseto = document.getElementById('url_field'); |
||||
893 | browseto.setAttribute('value', 'http://'); |
||||
894 | } |
||||
895 | |||||
896 | // lastJSON is used to reduce the database polling rate. |
||||
897 | var lastJSON = ''; |
||||
898 | |||||
899 | function pollDatabase() { |
||||
900 | var xmlHttp = new XMLHttpRequest(); |
||||
901 | if (xmlHttp) { |
||||
902 | xmlHttp.open("get", 'db.php?json=' + lastJSON, true); |
||||
903 | xmlHttp.onreadystatechange = function () { |
||||
904 | if (xmlHttp.readyState == 2) { |
||||
905 | // Data transferred to server. |
||||
906 | } else if (xmlHttp.readyState == 3) { |
||||
907 | // Server is answering. |
||||
908 | } else if (xmlHttp.readyState == 4) { |
||||
909 | // Received all data from server. |
||||
910 | var status = xmlHttp.status; |
||||
911 | if (status == 200) { |
||||
912 | // Got valid response. |
||||
913 | var text = xmlHttp.responseText; |
||||
914 | lastJSON = text; |
||||
915 | var db = JSON.parse(text); |
||||
916 | var i; |
||||
917 | var layout = ''; |
||||
918 | for (i = 0; i < db.setting.length; i++) { |
||||
919 | if (db.setting[i].key == 'layout') { |
||||
920 | layout = db.setting[i].value; |
||||
921 | break; |
||||
922 | } |
||||
923 | } |
||||
924 | var controls = updateControlsBySection(db.window); |
||||
925 | // for (i = 0; i < controls.length; i++) { |
||||
926 | // console.log(i + ": " + controls[i]); |
||||
927 | // } |
||||
928 | updateUserList(db.address, db.user); |
||||
929 | updateWindowList(db.window); |
||||
930 | showLayout(layout, controls, db.window); |
||||
931 | // updateScreen(db.window); |
||||
932 | setTimeout("pollDatabase()", 1); |
||||
933 | } else { |
||||
934 | // Got error. TODO: handle it. |
||||
935 | } |
||||
936 | } else { |
||||
937 | // Got unexpected xmlHttp.readyState. TODO: handle it. |
||||
938 | } |
||||
939 | }; |
||||
940 | xmlHttp.send(null); |
||||
941 | } |
||||
942 | } |
||||
943 | |||||
944 | // Start polling the database. |
||||
945 | pollDatabase(); |
||||
946 | |||||
947 | |||||
948 | function getOS() { |
||||
949 | var OSName="Unknown OS"; |
||||
950 | if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows"; |
||||
951 | if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS"; |
||||
952 | if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX"; |
||||
953 | if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux"; |
||||
954 | if (navigator.userAgent.indexOf("Android")!=-1) OSName="Android"; |
||||
955 | if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) OSName="iOS"; |
||||
956 | /* Source for Android and iOS: |
||||
957 | https://davidwalsh.name/detect-android |
||||
958 | https://davidwalsh.name/detect-iphone |
||||
959 | https://davidwalsh.name/detect-ipad */ |
||||
960 | return OSName; |
||||
961 | } |
||||
962 | |||||
963 | function getFilePathByOS() { |
||||
964 | var OSName = getOS(); |
||||
965 | var windows = 'download-winvnc'; |
||||
966 | var macOS = 'download-macvnc'; |
||||
967 | var linux = 'download-linux'; |
||||
968 | var download = ''; |
||||
969 | switch(OSName) { |
||||
970 | case 'Windows': download = windows; |
||||
971 | break; |
||||
972 | case 'MacOS': download = macOS; |
||||
973 | break; |
||||
974 | case 'Linux': download = linux; |
||||
975 | break; |
||||
976 | case 'UNIX': download = linux; |
||||
977 | break; |
||||
978 | case 'Android': |
||||
979 | case 'iOS': |
||||
980 | document.getElementById("Screen").innerHTML = '<div class="description"><?=__('Sorry! Screensharing for your device is currently not supported.')?></div>'; |
||||
981 | break; |
||||
982 | default: download = null; |
||||
983 | } |
||||
984 | document.getElementById(download).click(); |
||||
985 | } |
||||
986 | |||||
987 | function openTab(evt, tabName) { |
||||
988 | var i, tabcontent, tablinks; |
||||
989 | // Hide all elements with class="tabcontent" |
||||
990 | tabcontent = document.getElementsByClassName("tabcontent"); |
||||
991 | for (i = 0; i < tabcontent.length; i++) { |
||||
992 | tabcontent[i].style.display = "none"; |
||||
993 | } |
||||
994 | // Remove "active" class from all elements with class="tablinks" |
||||
995 | tablinks = document.getElementsByClassName("tablinks"); |
||||
996 | for (i = 0; i < tablinks.length; i++) { |
||||
997 | tablinks[i].className = tablinks[i].className.replace(" active", ""); |
||||
998 | } |
||||
999 | |||||
1000 | // Show current tab and add "active" class to the opening button |
||||
1001 | document.getElementById(tabName).style.display = "block"; |
||||
1002 | evt.currentTarget.className += " active"; |
||||
1003 | } |
||||
1004 | |||||
1005 | function openSubtab(evt, tabName, subtabName) { |
||||
1006 | var i, tab, subtabcontent, subtablinks; |
||||
1007 | // Hide all elements with class="subtabcontent" |
||||
1008 | tab = document.getElementById(tabName); |
||||
1009 | subtabcontent = tab.getElementsByClassName("subtabcontent"); |
||||
1010 | for (i = 0; i < subtabcontent.length; i++) { |
||||
1011 | subtabcontent[i].style.display = "none"; |
||||
1012 | } |
||||
1013 | |||||
1014 | // Remove "active" class from all elements with class="subtablinks" |
||||
1015 | subtablinks = tab.getElementsByClassName("subtablinks"); |
||||
1016 | for (i = 0; i < subtablinks.length; i++) { |
||||
1017 | subtablinks[i].className = subtablinks[i].className.replace(" active", ""); |
||||
1018 | } |
||||
1019 | |||||
1020 | // Show current subtab and add "active" class to the opening button |
||||
1021 | document.getElementById(subtabName).style.display = "block"; |
||||
1022 | evt.currentTarget.className += " active"; |
||||
1023 | } |
||||
1024 | |||||
1025 | function openAccordion(divID) { |
||||
1026 | var button = document.getElementById(divID).firstChild; |
||||
1027 | var windowcontrols = document.getElementById(divID).lastChild; |
||||
1028 | if (windowcontrols.style.display == "block") { |
||||
1029 | windowcontrols.style.display = "none"; |
||||
1030 | button.setAttribute("class", "window_entry_button"); |
||||
1031 | } else if (windowcontrols.style.display == "none") { |
||||
1032 | windowcontrols.style.display = "block"; |
||||
1033 | button.setAttribute("class", "window_entry_button active"); |
||||
1034 | } else { |
||||
1035 | windowcontrols.style.display = "block"; |
||||
1036 | button.setAttribute("class", "window_entry_button active"); |
||||
1037 | } |
||||
1038 | } |
||||
1039 | |||||
1040 | function showDropdown() { |
||||
1041 | document.getElementById("languageSelection").classList.toggle("show"); |
||||
1042 | } |
||||
1043 | // Close the dropdown menu if the user clicks outside of it |
||||
1044 | // Must use some workaround to support IE. |
||||
1045 | window.onclick = function(event) { |
||||
1046 | var classes = event.target.className.split(' '); |
||||
1047 | var found = false; var i = 0; |
||||
1048 | while (i < classes.length && !found) { |
||||
1049 | if (classes[i]=='dropbutton') found = true; |
||||
1050 | else ++i; |
||||
1051 | } |
||||
1052 | if (!found) { |
||||
1053 | var dropdowns = document.getElementsByClassName("dropdown-content"); |
||||
1054 | var i; |
||||
1055 | for (i = 0; i < dropdowns.length; i++) { |
||||
1056 | var openDropdown = dropdowns[i]; |
||||
1057 | if (openDropdown.classList.contains('show')) { |
||||
1058 | openDropdown.classList.remove('show'); |
||||
1059 | } |
||||
1060 | } |
||||
1061 | } |
||||
1062 | } |
||||
1063 | </script> |
||||
1064 | </head> |
||||
1065 | |||||
1066 | <body> |
||||
1067 | |||||
1068 | <!-- This formating is used to prevent empty textnodes that interfere with the design --> |
||||
1069 | <div class="tab" |
||||
1070 | ><button class="tablinks" onclick="openTab(event, 'Add')"><?=__('Add')?><i class="fa fa-plus"></i></button |
||||
1071 | ><button class="tablinks" id="controlbtn" onclick="openTab(event, 'Control')"><?=__('Control')?><i class="fa fa-arrows"></i></button |
||||
1072 | ><button class="tablinks" onclick="openTab(event, 'Extras')"><?=__('Extras')?><i class="fa fa-info-circle"></i></button |
||||
1073 | ></div> |
||||
1074 | |||||
1075 | <div id="workbench"> |
||||
1076 | <div id="Add" class="tabcontent"> |
||||
1077 | <div class="subtab" |
||||
1078 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'File')"><?=__('File')?><i class="fa fa-file"></i></button |
||||
1079 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'URL')"><?=__('URL')?><i class="fa fa-globe"></i></button |
||||
1080 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'Screen')"><?=__('Screen')?><i class="fa fa-video-camera"></i></button |
||||
1081 | ></div> |
||||
1082 | <div id="File" class="subtabcontent"> |
||||
1083 | <div id="file_upload"> |
||||
1084 | <form action="upload.php" |
||||
1085 | class="dropzone" |
||||
1086 | id="palma-dropzone" |
||||
1087 | title="<?=__('Drag and drop files or click here to upload.')?>"> |
||||
1088 | <div class="dz-default dz-message"> |
||||
1089 | <?=__('Add file (click or drop here)')?> |
||||
1090 | <i class="fa fa-file fa-2x"></i> |
||||
1091 | </div> |
||||
1092 | </form> |
||||
1093 | <div class="dz-preview dz-file-preview"> |
||||
1094 | <div class="dz-details"> |
||||
1095 | <div class="dz-filename"><span data-dz-name></span></div> |
||||
1096 | <div class="dz-size" data-dz-size></div> |
||||
1097 | <img data-dz-thumbnail src="" alt=""> |
||||
1098 | </div> |
||||
1099 | <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> |
||||
1100 | <div class="dz-success-mark"><span> </span></div> |
||||
1101 | <div class="dz-error-mark"><span> </span></div> |
||||
1102 | <div class="dz-error-message"><span data-dz-errormessage></span></div> |
||||
1103 | </div> |
||||
1104 | </div> |
||||
1105 | </div> |
||||
1106 | <div id="URL" class="subtabcontent"> |
||||
1107 | <div> |
||||
1108 | <input type="text" value="<?=__('Add webpage')?>" |
||||
1109 | id="url_field" maxlength="256" size="46" |
||||
1110 | onkeydown="if (event.keyCode == 13) document.getElementById('url_button').click()" |
||||
1111 | onfocus="clearURLField('<?=__('Enter URL')?>')"> |
||||
1112 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1113 | id="url_button" |
||||
1114 | onClick="urlToNuc()" title="<?=__('Click here to show the webpage on the screen.')?>"> |
||||
1115 | <?=__('Enter')?><i class="fa fa-globe"></i> |
||||
1116 | </button> |
||||
1117 | </div> |
||||
1118 | </div> |
||||
1119 | <div id="Screen" class="subtabcontent"> |
||||
1120 | <div id="vnc-button" onclick="javascript:getFilePathByOS()"> |
||||
1121 | <div id="vnc-button-container"> |
||||
1122 | <div id="vnc-button-label"><?=__('Add your screen')?><i class="fa fa-video-camera fa-2x" aria-hidden="true"></i></div> |
||||
1123 | <div id="vnc-button-label-subtext"><?=__('Download screensharing tool')?></div> |
||||
1124 | </div> |
||||
1125 | <a href="<?php echo $winvnc; ?>" download id="download-winvnc" hidden></a> |
||||
1126 | <a href="<?php echo $macvnc; ?>" download id="download-macvnc" hidden></a> |
||||
1127 | <a href="<?php echo $linuxsh; ?>" download id="download-linux" hidden></a> |
||||
1128 | </div> |
||||
1129 | <div class="description"> |
||||
1130 | <?=__('Download your screensharing tool (Windows, Mac and Linux only). Visit the help section for further information.')?> |
||||
1131 | </div> |
||||
1132 | </div> |
||||
1133 | </div> |
||||
1134 | <div id="Control" class="tabcontent"> |
||||
1135 | <div class="subtab" |
||||
1136 | ><button class="subtablinks" onclick="openSubtab(event, 'Control', 'Layout')"><?=__('Layout')?><i class="fa fa-desktop"></i></button |
||||
1137 | ><button class="subtablinks" onclick="openSubtab(event, 'Control', 'Navigate')"><?=__('Navigate')?><i class="fa fa-arrows"></i></button |
||||
1138 | ></div> |
||||
1139 | <div id="Layout" class="subtabcontent"> |
||||
1140 | <div class="screenlayout"> |
||||
1141 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1142 | id="g1x1" onclick="miniDisplaySelect(this)" |
||||
1143 | title="<?=__('Choose screen layout')?>"> |
||||
1144 | <i alt="1" class="fa fa-desktop fa-2x" aria-hidden="true"></i> |
||||
1145 | </button> |
||||
1146 | </div |
||||
1147 | ><div class="screenlayout vertical"> |
||||
1148 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1149 | id="g1x2" onclick="miniDisplaySelect(this)" |
||||
1150 | title="<?=__('Choose screen layout')?>"> |
||||
1151 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1152 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1153 | </button> |
||||
1154 | </div |
||||
1155 | ><div class="screenlayout"> |
||||
1156 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1157 | id="g2x1" onclick="miniDisplaySelect(this)" |
||||
1158 | title="<?=__('Choose screen layout')?>"> |
||||
1159 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1160 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1161 | </button> |
||||
1162 | </div |
||||
1163 | ><div class="screenlayout"> |
||||
1164 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1165 | id="g1a2" onclick="miniDisplaySelect(this)" |
||||
1166 | title="<?=__('Choose screen layout')?>"> |
||||
1167 | <div class="layout_left"> |
||||
1168 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1169 | </div> |
||||
1170 | <div class="layout_right vertical"> |
||||
1171 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1172 | <i alt="3" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1173 | </div> |
||||
1174 | </button> |
||||
1175 | </div |
||||
1176 | ><div class="screenlayout"> |
||||
1177 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1178 | id="g2x2" onclick="miniDisplaySelect(this)" |
||||
1179 | title="<?=__('Choose screen layout')?>"> |
||||
1180 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1181 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1182 | <br /> |
||||
1183 | <i alt="3" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1184 | <i alt="4" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||||
1185 | </button> |
||||
1186 | </div> |
||||
1187 | </div> |
||||
1188 | <div id="Navigate" class="subtabcontent"> |
||||
1189 | <div id="windowlist"> |
||||
1190 | <!-- filled by updateWindowList and showLayout --> |
||||
1191 | </div> |
||||
1192 | <button id="closeWindows" class="pure-button pure-button-primary pure-input-rounded" |
||||
1193 | onClick="sendToNuc('closeAll=TRUE')" |
||||
1194 | title="<?=__('Close all windows and remove uploaded files')?>"> |
||||
1195 | <?=__('Delete all items')?> |
||||
1196 | </button> |
||||
1197 | </div> |
||||
1198 | </div> |
||||
1199 | <div id="Extras" class="tabcontent"> |
||||
1200 | <div class="subtab" |
||||
1201 | ><button class="subtablinks active" onclick="openSubtab(event, 'Extras', 'Help')"><?=__('Help')?><i class="fa fa-question-circle"></i></button |
||||
1202 | ><button class="subtablinks" onclick="openSubtab(event, 'Extras', 'Feedback')"><?=__('Feedback')?><i class="fa fa-thumbs-o-up"></i></button |
||||
1203 | ><button class="subtablinks" onclick="openSubtab(event, 'Extras', 'Users')"><?=__('Users')?><i class="fa fa-users"></i></button |
||||
1204 | ></div> |
||||
1205 | <div id="Help" class="subtabcontent"> |
||||
1206 | <p><?=__('With PalMA, you can share documents, websites and your desktop with your learning group.')?> |
||||
1207 | <?=__('The PalMA team monitor shows up to four contributions simultaneously.')?></p> |
||||
1208 | <?php |
||||
1209 | if (CONFIG_INSTITUTION_URL) { ?> |
||||
1210 | <p><?=__('For further information about PalMA in this institution')?> <a href=<?=CONFIG_INSTITUTION_URL?> target="_blank"><?=__('see here.')?></a></p> |
||||
1211 | <?php |
||||
1212 | } |
||||
1213 | ?> |
||||
1214 | <h4><?=__('Connect')?><i class="fa fa-wifi"></i></h4> |
||||
1215 | <p><?=__('Team members can join the session at any time with this URL or QR-Code:')?></p> |
||||
1216 | <p class="url_hint"><?=$_SESSION['starturl']?><br /> |
||||
1217 | <?php |
||||
1218 | if (!empty($_SESSION['pin'])) { |
||||
1219 | echo __('PIN: '); |
||||
1220 | echo $_SESSION['pin']; |
||||
1221 | } |
||||
1222 | ?> |
||||
1223 | </p> |
||||
1224 | <img class="qr-code" src="qrcode/php/qr_img.php?d=<?=$_SESSION['starturl']?>?pin=<?=$_SESSION['pin']?>" alt="QR Code"> |
||||
1225 | |||||
1226 | <h4><?=__('Add')?><i class="fa fa-plus"></i></h4> |
||||
1227 | <p><?=__('Use the Add-Section to share content on the PalMA monitor.')?></p> |
||||
1228 | <ul> |
||||
1229 | <li><i class="fa fa-file"></i> <?=__('For PDF files, office files, images or videos use the file section.')?></li> |
||||
1230 | <li><i class="fa fa-globe"></i> <?=__('To display a website use the URL field.')?></li> |
||||
1231 | <li><i class="fa fa-video-camera"></i> <?=__('To share your desktop in real time download the VNC screen sharing software and')?></li> |
||||
1232 | <ul> |
||||
1233 | <li><i class="fa fa-windows"></i> <?=__('Windows:')?></li> |
||||
1234 | <ul> |
||||
1235 | <li><?=__('Run the downloaded file.')?></li> |
||||
1236 | <li><?=__('Double-click the name of your PalMA station in the appearing list.')?></li> |
||||
1237 | </ul> |
||||
1238 | <li><i class="fa fa-apple"> </i> <?=__('Mac:')?></li> |
||||
1239 | <ul> |
||||
1240 | <li><?=__('CTRL + click the downloaded file and run it.')?></li> |
||||
1241 | <li><?=__('A second window opens, in which you can start "VineServer".')?></li> |
||||
1242 | <li><?=__('In the upper left corner, click on "VNC Server".')?></li> |
||||
1243 | <li><?=__('Select "Reverse Connection".')?></li> |
||||
1244 | <li><?=__('Enter the URL of your PalMA station and click "Connect".')?></li> |
||||
1245 | </ul> |
||||
1246 | <li><i class="fa fa-linux"></i> <?=__('Linux:')?></li> |
||||
1247 | <ul> |
||||
1248 | <li><?=__('Run the downloaded shell script.')?></li> |
||||
1249 | <li><?=__('Or use this shell command:')?> <code>x11vnc -connect <?=$_SERVER['HTTP_HOST']?></code></li> |
||||
1250 | </ul> |
||||
1251 | </ul> |
||||
1252 | </ul> |
||||
1253 | <h4><?=__('Control')?><i class="fa fa-arrows"></i></h4> |
||||
1254 | <p><?=__('With the grey monitor buttons at the top you can choose how the shared content should be arranged on the PalMA monitor.')?></p> |
||||
1255 | <p><?=__('Below that you find the controls for each item:')?></p> |
||||
1256 | <ul> |
||||
1257 | <li><?=__('In the top bar you can')?></li> |
||||
1258 | <ul> |
||||
1259 | <li><?=__('Hide and show')?><i class="fa fa-eye"></i>,</li> |
||||
1260 | <li><?=__('Zoom in and out')?><i class="fa fa-search-plus"></i><i class="fa fa-search-minus"></i>,</li> |
||||
1261 | <li><?=__('Rotate')?><i class="fa fa-rotate-left"></i><i class="fa fa-rotate-right"></i>,</li> |
||||
1262 | <li><?=__('Download')?><i class="fa fa-download"></i>,</li> |
||||
1263 | <li><?=__('Delete the item')?><i class="fa fa-trash-o"></i>.</li> |
||||
1264 | </ul> |
||||
1265 | <li><?=__('Below you find the navigation controls.')?></li> |
||||
1266 | <ul> |
||||
1267 | <li><?=__('Buttons on the left jump to the top, to the end, a page up or a page down')?><i class="fa fa-angle-double-up"></i><i class="fa fa-angle-up"></i><i class="fa fa-angle-down"></i><i class="fa fa-angle-double-up"></i>.</li> |
||||
1268 | <li><?=__('Arrow buttons in the middle scroll gradually')?><i class="fa fa-toggle-up"></i><i class="fa fa-toggle-down"></i><i class="fa fa-toggle-left"></i><i class="fa fa-toggle-right"></i>.</li> |
||||
1269 | </ul> |
||||
1270 | </li> |
||||
1271 | <li><?=__('On the right you can choose the position on the PalMA monitor')?><i class="fa fa-desktop"></i>.</li> |
||||
1272 | </ul> |
||||
1273 | <p><?=__('Controls that are not available for certain kinds of content are marked grey.')?></p> |
||||
1274 | <h4><?=__('Extras')?><i class="fa fa-info-circle"></i></h4> |
||||
1275 | <p><?=__('Some additional features are:')?></p> |
||||
1276 | <ul> |
||||
1277 | <li><i class="fa fa-question-circle"></i> <?=__('This help,')?></li> |
||||
1278 | <li><i class="fa fa-thumbs-o-up"></i> <?=__('Your chance to recommend us or give us your thoughts in the "Feedback" section,')?></li> |
||||
1279 | <li><i class="fa fa-users"></i> <?=__('A list of all logged-in users as well as a button to disconnect everyone and therefore end the session.')?></li> |
||||
1280 | </ul> |
||||
1281 | </div> |
||||
1282 | <div id="Feedback" class="subtabcontent"> |
||||
1283 | <div id="recommendcontainer"> |
||||
1284 | <h3> |
||||
1285 | <?=__('Recommend us')?> |
||||
1286 | </h3> |
||||
1287 | <div> |
||||
1288 | <p><?=__('If you like PalMA, please recommend us by sharing in your social networks.<br />Enjoy PalMA!')?></p> |
||||
1289 | <!-- Social Media Button Integration, Source: http://sharingbuttons.io/ --> |
||||
1290 | <?php $github_url = "https%3A%2F%2Fgithub.com/UB-Mannheim/PalMA/blob/master/README.md"; ?> |
||||
1291 | |||||
1292 | <!-- Sharingbutton Facebook --> |
||||
1293 | <a class="resp-sharing-button__link" href="https://facebook.com/sharer/sharer.php?u=<?=$github_url?>" target="_blank" aria-label=""> |
||||
1294 | <div class="resp-sharing-button resp-sharing-button--facebook resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1295 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.77 7.46H14.5v-1.9c0-.9.6-1.1 1-1.1h3V.5h-4.33C10.24.5 9.5 3.44 9.5 5.32v2.15h-3v4h3v12h5v-12h3.85l.42-4z"/></svg> |
||||
1296 | </div> |
||||
1297 | </div> |
||||
1298 | </a> |
||||
1299 | |||||
1300 | <!-- Sharingbutton Twitter --> |
||||
1301 | <a class="resp-sharing-button__link" href="https://twitter.com/intent/tweet/?text=Do%20you%20already%20know%20PalMA?%20Take%20a%20Look.&url=<?=$github_url?>" target="_blank" aria-label=""> |
||||
1302 | <div class="resp-sharing-button resp-sharing-button--twitter resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1303 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23.44 4.83c-.8.37-1.5.38-2.22.02.93-.56.98-.96 1.32-2.02-.88.52-1.86.9-2.9 1.1-.82-.88-2-1.43-3.3-1.43-2.5 0-4.55 2.04-4.55 4.54 0 .36.03.7.1 1.04-3.77-.2-7.12-2-9.36-4.75-.4.67-.6 1.45-.6 2.3 0 1.56.8 2.95 2 3.77-.74-.03-1.44-.23-2.05-.57v.06c0 2.2 1.56 4.03 3.64 4.44-.67.2-1.37.2-2.06.08.58 1.8 2.26 3.12 4.25 3.16C5.78 18.1 3.37 18.74 1 18.46c2 1.3 4.4 2.04 6.97 2.04 8.35 0 12.92-6.92 12.92-12.93 0-.2 0-.4-.02-.6.9-.63 1.96-1.22 2.56-2.14z"/></svg> |
||||
1304 | </div> |
||||
1305 | </div> |
||||
1306 | </a> |
||||
1307 | |||||
1308 | <!-- Sharingbutton Google+ --> |
||||
1309 | <a class="resp-sharing-button__link" href="https://plus.google.com/share?url=<?=$github_url?>" target="_blank" aria-label=""> |
||||
1310 | <div class="resp-sharing-button resp-sharing-button--google resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1311 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.37 12.93c-.73-.52-1.4-1.27-1.4-1.5 0-.43.03-.63.98-1.37 1.23-.97 1.9-2.23 1.9-3.57 0-1.22-.36-2.3-1-3.05h.5c.1 0 .2-.04.28-.1l1.36-.98c.16-.12.23-.34.17-.54-.07-.2-.25-.33-.46-.33H7.6c-.66 0-1.34.12-2 .35-2.23.76-3.78 2.66-3.78 4.6 0 2.76 2.13 4.85 5 4.9-.07.23-.1.45-.1.66 0 .43.1.83.33 1.22h-.08c-2.72 0-5.17 1.34-6.1 3.32-.25.52-.37 1.04-.37 1.56 0 .5.13.98.38 1.44.6 1.04 1.84 1.86 3.55 2.28.87.23 1.82.34 2.8.34.88 0 1.7-.1 2.5-.34 2.4-.7 3.97-2.48 3.97-4.54 0-1.97-.63-3.15-2.33-4.35zm-7.7 4.5c0-1.42 1.8-2.68 3.9-2.68h.05c.45 0 .9.07 1.3.2l.42.28c.96.66 1.6 1.1 1.77 1.8.05.16.07.33.07.5 0 1.8-1.33 2.7-3.96 2.7-1.98 0-3.54-1.23-3.54-2.8zM5.54 3.9c.33-.38.75-.58 1.23-.58h.05c1.35.05 2.64 1.55 2.88 3.35.14 1.02-.08 1.97-.6 2.55-.32.37-.74.56-1.23.56h-.03c-1.32-.04-2.63-1.6-2.87-3.4-.13-1 .08-1.92.58-2.5zM23.5 9.5h-3v-3h-2v3h-3v2h3v3h2v-3h3"/></svg> |
||||
1312 | </div> |
||||
1313 | </div> |
||||
1314 | </a> |
||||
1315 | |||||
1316 | <!-- Sharingbutton E-Mail --> |
||||
1317 | <a class="resp-sharing-button__link" href="mailto:?subject=Do%20you%20already%20know%20PalMA?%20Take%20a%20Look.&body=<?=$github_url?>" target="_self" aria-label=""> |
||||
1318 | <div class="resp-sharing-button resp-sharing-button--email resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1319 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22 4H2C.9 4 0 4.9 0 6v12c0 1.1.9 2 2 2h20c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7.25 14.43l-3.5 2c-.08.05-.17.07-.25.07-.17 0-.34-.1-.43-.25-.14-.24-.06-.55.18-.68l3.5-2c.24-.14.55-.06.68.18.14.24.06.55-.18.68zm4.75.07c-.1 0-.2-.03-.27-.08l-8.5-5.5c-.23-.15-.3-.46-.15-.7.15-.22.46-.3.7-.14L12 13.4l8.23-5.32c.23-.15.54-.08.7.15.14.23.07.54-.16.7l-8.5 5.5c-.08.04-.17.07-.27.07zm8.93 1.75c-.1.16-.26.25-.43.25-.08 0-.17-.02-.25-.07l-3.5-2c-.24-.13-.32-.44-.18-.68s.44-.32.68-.18l3.5 2c.24.13.32.44.18.68z"/></svg> |
||||
1320 | </div> |
||||
1321 | </div> |
||||
1322 | </a> |
||||
1323 | |||||
1324 | <!-- Sharingbutton WhatsApp --> |
||||
1325 | <a class="resp-sharing-button__link" href="whatsapp://send?text=Do%20you%20already%20know%20PalMA?%20Take%20a%20Look.%20<?=$github_url?>" target="_blank" aria-label=""> |
||||
1326 | <div class="resp-sharing-button resp-sharing-button--whatsapp resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1327 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.1 3.9C17.9 1.7 15 .5 12 .5 5.8.5.7 5.6.7 11.9c0 2 .5 3.9 1.5 5.6L.6 23.4l6-1.6c1.6.9 3.5 1.3 5.4 1.3 6.3 0 11.4-5.1 11.4-11.4-.1-2.8-1.2-5.7-3.3-7.8zM12 21.4c-1.7 0-3.3-.5-4.8-1.3l-.4-.2-3.5 1 1-3.4L4 17c-1-1.5-1.4-3.2-1.4-5.1 0-5.2 4.2-9.4 9.4-9.4 2.5 0 4.9 1 6.7 2.8 1.8 1.8 2.8 4.2 2.8 6.7-.1 5.2-4.3 9.4-9.5 9.4zm5.1-7.1c-.3-.1-1.7-.9-1.9-1-.3-.1-.5-.1-.7.1-.2.3-.8 1-.9 1.1-.2.2-.3.2-.6.1s-1.2-.5-2.3-1.4c-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6s.3-.3.4-.5c.2-.1.3-.3.4-.5.1-.2 0-.4 0-.5C10 9 9.3 7.6 9 7c-.1-.4-.4-.3-.5-.3h-.6s-.4.1-.7.3c-.3.3-1 1-1 2.4s1 2.8 1.1 3c.1.2 2 3.1 4.9 4.3.7.3 1.2.5 1.6.6.7.2 1.3.2 1.8.1.6-.1 1.7-.7 1.9-1.3.2-.7.2-1.2.2-1.3-.1-.3-.3-.4-.6-.5z"/></svg> |
||||
1328 | </div> |
||||
1329 | </div> |
||||
1330 | </a> |
||||
1331 | |||||
1332 | <!-- Sharingbutton Telegram --> |
||||
1333 | <a class="resp-sharing-button__link" href="https://telegram.me/share/url?text=Do%20you%20already%20know%20PalMA?%20Take%20a%20Look.&url=<?=$github_url?>" target="_blank" aria-label=""> |
||||
1334 | <div class="resp-sharing-button resp-sharing-button--telegram resp-sharing-button--small"><div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid"> |
||||
1335 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M.707 8.475C.275 8.64 0 9.508 0 9.508s.284.867.718 1.03l5.09 1.897 1.986 6.38a1.102 1.102 0 0 0 1.75.527l2.96-2.41a.405.405 0 0 1 .494-.013l5.34 3.87a1.1 1.1 0 0 0 1.046.135 1.1 1.1 0 0 0 .682-.803l3.91-18.795A1.102 1.102 0 0 0 22.5.075L.706 8.475z"/></svg> |
||||
1336 | </div> |
||||
1337 | </div> |
||||
1338 | </a> |
||||
1339 | </div> <!-- Social media buttons and description --> |
||||
1340 | </div> <!-- recommendcontainer --> |
||||
1341 | <div id="contactcontainer"> |
||||
1342 | <h3><?=__('Tell us what you think')?></h3> |
||||
1343 | <div> |
||||
1344 | <p><?=__('Please let us know about problems or ideas to improve PalMA. Help us directly by sending crash reports or contributing on ')?><a href="https://github.com/UB-Mannheim/PalMA" target="_blank">GitHub</a>.<br /><?=__('Thank you!')?></p> |
||||
1345 | <iframe width="100%" height="500" frameborder="0" src="https://www.bib.uni-mannheim.de/palma/feedback/form"></iframe> |
||||
1346 | </div> |
||||
1347 | </div> <!-- contactcontainer --> |
||||
1348 | </div> <!-- feedback --> |
||||
1349 | <div id="Users" class="subtabcontent"> |
||||
1350 | <div class="dropdown"> |
||||
1351 | <button onclick="showDropdown()" class="dropbutton pure-button pure-button-primary"><?=__('Select language:')?> <?=substr($locale, 0, 2)?><i class="fa fa-caret-down"></i></button> |
||||
1352 | <div id="languageSelection" class="dropdown-content"> |
||||
1353 | <?php |
||||
1354 | $dirs = array_slice(scandir('locale'), 2); |
||||
0 ignored issues
–
show
It seems like
scandir('locale') can also be of type false ; however, parameter $array of array_slice() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
1355 | $langs = []; |
||||
1356 | for ($n = 0; $n < count($dirs); $n++) { |
||||
1357 | if (is_dir("locale/$dirs[$n]")) { |
||||
1358 | array_push($langs, substr($dirs[$n], 0, 2)); |
||||
1359 | } |
||||
1360 | } |
||||
1361 | for ($i = 0; $i < count($langs); $i++) { |
||||
1362 | echo "<a href=$_SERVER[PHP_SELF]?lang=$langs[$i]>$langs[$i]</a>"; |
||||
1363 | } |
||||
1364 | ?> |
||||
1365 | </div> |
||||
1366 | </div> |
||||
1367 | <div class="list_container"> |
||||
1368 | <table class="userlist" summary="<?=__('User list')?>" title="<?=__('List of connected users')?>"> |
||||
1369 | <tbody id="userlist"> |
||||
1370 | <tr><td><!-- filled by updateUserList() --></td></tr> |
||||
1371 | </tbody> |
||||
1372 | </table> |
||||
1373 | <div class="description"> |
||||
1374 | <?=__('New users can join at')?><br /><?=$_SESSION['starturl']?><br /> |
||||
1375 | <?php |
||||
1376 | if (!empty($_SESSION['pin'])) { |
||||
1377 | echo __('PIN: '); |
||||
1378 | echo $_SESSION['pin']; |
||||
1379 | } |
||||
1380 | ?> |
||||
1381 | <img class="qr-code" src="qrcode/php/qr_img.php?d=<?=$_SESSION['starturl']?>?pin=<?=$_SESSION['pin']?>" alt="QR Code"> |
||||
1382 | </div> |
||||
1383 | <button class="pure-button pure-button-primary pure-input-rounded" |
||||
1384 | onClick="sendToNuc('logout=ALL')" |
||||
1385 | title="<?=__('Disconnect all users and end the session')?>"> |
||||
1386 | <?=__('End the session')?> |
||||
1387 | </button> |
||||
1388 | </div> |
||||
1389 | </div> |
||||
1390 | </div> |
||||
1391 | </div> <!-- workbench --> |
||||
1392 | |||||
1393 | <div id="footer"> |
||||
1394 | <?php |
||||
1395 | # Show authorized user name (and address) and allow logout. |
||||
1396 | if ($user) { |
||||
1397 | echo("<a href=\"logout.php\" title=\"" . |
||||
1398 | __('Disconnect the current user') . |
||||
1399 | "\">" . __('Log out') . "<i class=\"fa fa-sign-out\"></i></a>"); |
||||
1400 | } |
||||
1401 | ?> |
||||
1402 | </div> <!-- Footer --> |
||||
1403 | |||||
1404 | <?php |
||||
1405 | |||||
1406 | $plugin_dir = "plugins/"; |
||||
1407 | $stats = "piwik.php"; |
||||
1408 | |||||
1409 | if (file_exists($plugin_dir . $stats)) { |
||||
1410 | include $plugin_dir . $stats; |
||||
1411 | } |
||||
1412 | |||||
1413 | ?> |
||||
1414 | |||||
1415 | </body> |
||||
1416 | </html> |
||||
1417 |