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 = CONFIG_START_URL . "theme/" . CONFIG_THEME . "/osx-vnc.dmg"; |
||
86 | $linuxsh = CONFIG_START_URL . "theme/" . CONFIG_THEME . "/x11.sh"; |
||
87 | |||
88 | ?> |
||
89 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" |
||
90 | "http://www.w3.org/TR/html4/strict.dtd"> |
||
91 | |||
92 | <html> |
||
93 | |||
94 | <head> |
||
95 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||
96 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
||
97 | <title>PalMA</title> |
||
98 | |||
99 | <link rel="icon" href="theme/<?=CONFIG_THEME?>/favicon.ico" type="image/x-icon"> |
||
100 | <link rel="stylesheet" href="font-awesome/css/font-awesome.min.css"> |
||
101 | <link rel="stylesheet" href="pure-min.css"> |
||
102 | <link rel="stylesheet" href="palma.css" type="text/css"> |
||
103 | |||
104 | <script type="text/javascript" src="jquery.min.js"></script> |
||
105 | |||
106 | <script type="text/javascript" src="dropzone.js"></script> |
||
107 | |||
108 | <script type="text/javascript"> |
||
109 | |||
110 | // Screen section which responds to keyboard input. |
||
111 | var focus_section = '1'; |
||
112 | |||
113 | function sendToNuc(command) { |
||
114 | var xmlHttp = new XMLHttpRequest(); |
||
115 | if (!xmlHttp) { |
||
116 | // TODO |
||
117 | alert('XMLHttpRequest failed!'); |
||
118 | return; |
||
119 | } |
||
120 | var url = 'control.php?' + command; |
||
121 | var response = ""; |
||
122 | xmlHttp.open("get", url, true); |
||
123 | xmlHttp.onreadystatechange = function () { |
||
124 | if (xmlHttp.readyState == 1) { |
||
125 | // Server connection established (IE only). |
||
126 | } else if (xmlHttp.readyState == 2) { |
||
127 | // Data transferred to server. |
||
128 | } else if (xmlHttp.readyState == 3) { |
||
129 | // Server is answering. |
||
130 | } else if (xmlHttp.readyState == 4) { |
||
131 | // Received all data from server. |
||
132 | return xmlHttp.responseText; |
||
133 | } else { |
||
134 | alert("Got xmlHttp.readyState " + xmlHttp.readyState); |
||
135 | } |
||
136 | }; |
||
137 | xmlHttp.send(null); |
||
138 | //~ alert("sendToNuc " + url); |
||
139 | } |
||
140 | |||
141 | function keyControl(number, image, controlClass, key, handler, disabled, title) { |
||
142 | // "number" refers to the slected screensection |
||
143 | |||
144 | var keyHandler = getHandlerCommand(handler, key); |
||
145 | if ( (keyHandler == "") || (keyHandler == null) ) { |
||
146 | keyHandler = "default"; |
||
147 | } |
||
148 | var button = document.createElement('button'); |
||
149 | var icon = document.createElement('i'); |
||
150 | if (!disabled) { |
||
151 | icon.setAttribute('class', image); |
||
152 | button.appendChild(icon); |
||
153 | button.setAttribute('class', controlClass); |
||
154 | button.setAttribute('onmousedown', |
||
155 | 'sendToNuc("window=' + number + '&keydown=' + encodeURIComponent(keyHandler) + '")'); |
||
156 | button.setAttribute('onmouseup', |
||
157 | 'sendToNuc("window=' + number + '&keyup=' + encodeURIComponent(keyHandler) + '")'); |
||
158 | button.setAttribute('title', title); |
||
159 | } else { |
||
160 | icon.setAttribute('class', image + " unavailable"); |
||
161 | button.appendChild(icon); |
||
162 | button.setAttribute("class", "unavailable"); |
||
163 | button.setAttribute('title', title + " " + "<?=addslashes(__('not available'))?>"); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
164 | } |
||
165 | return button; |
||
166 | } |
||
167 | |||
168 | function downloadFile(screensection) { |
||
169 | |||
170 | // wrong path if copied to /home/directory |
||
171 | // TODO: check file and path |
||
172 | |||
173 | var url = document.URL; |
||
174 | var url_path = url.split("/"); |
||
175 | |||
176 | var file = document.getElementById("file" + screensection).innerHTML; |
||
177 | var file = document.getElementById("file" + screensection).getAttribute("title"); |
||
178 | |||
179 | // Download with download.php |
||
180 | var download = url_path[0]+"/"+url_path[1]+"/"+url_path[2]+"/"+url_path[3]+"/download.php?file="+encodeURIComponent(file); |
||
181 | |||
182 | var name = "Download"; |
||
183 | |||
184 | if(file.indexOf("www.") > -1) { |
||
185 | window.open(file, name); |
||
186 | } else { |
||
187 | window.open(download, name); |
||
188 | } |
||
189 | } |
||
190 | |||
191 | function is_valid_url(url) |
||
192 | { |
||
193 | return url.match(/(^(ht|f)tps?:\/\/)([a-zA-Z0-9\.-])+(\.([a-zA-Z]{2,}))?(\:([0-9]{1,5}))?(\/([^\s\<\>\,\{\}\\\|\^\[\]\'])*)?$/); |
||
194 | } |
||
195 | |||
196 | function urlToNuc() { |
||
197 | var url = document.getElementById('url_field').value; |
||
198 | if (is_valid_url(url)) { |
||
199 | // Encode special characters |
||
200 | url = encodeURIComponent(url); |
||
201 | sendToNuc('openURL='+url); |
||
202 | } else { |
||
203 | var urlfield = document.getElementById('url_field'); |
||
204 | urlfield.setAttribute('value', '<?=addslashes(__("Enter valid URL"))?>'); |
||
205 | } |
||
206 | |||
207 | setTimeout(function(){location.reload()}, 1000); |
||
208 | } |
||
209 | |||
210 | function showLayout(layout, controls, window) { |
||
211 | //~ console.log("Layout: " + layout); |
||
212 | //~ for (i = 0; i < controls.length; i++) { |
||
213 | //~ console.log("SL " + i + ": " + controls[i]); |
||
214 | //~ } |
||
215 | |||
216 | document.onkeydown = function(evt) { |
||
217 | evt = evt || window.event; |
||
218 | var section = focus_section; |
||
219 | var handler = controls[focus_section][0]; |
||
220 | var keyHandler; |
||
221 | //~ console.log("Key down: " + evt.keyCode); |
||
222 | switch (evt.keyCode) { |
||
223 | case 33: // page up |
||
224 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'prior')); |
||
225 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
226 | break; |
||
227 | case 34: // page down |
||
228 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'next')); |
||
229 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
230 | break; |
||
231 | case 35: // end |
||
232 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'end')); |
||
233 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
234 | break; |
||
235 | case 36: // home |
||
236 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'home')); |
||
237 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
238 | break; |
||
239 | case 37: // left |
||
240 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'left')); |
||
241 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
242 | break; |
||
243 | case 38: // up |
||
244 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'up')); |
||
245 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
246 | break; |
||
247 | case 39: // right |
||
248 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'right')); |
||
249 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
250 | break; |
||
251 | case 40: // down |
||
252 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'down')); |
||
253 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
254 | break; |
||
255 | } |
||
256 | }; |
||
257 | |||
258 | document.onkeypress = function(evt) { |
||
259 | evt = evt || window.event; |
||
260 | //~ console.log("Key press: " + evt.keyCode); |
||
261 | var charCode = evt.which || evt.keyCode; |
||
262 | var charStr = String.fromCharCode(charCode); |
||
263 | var section = focus_section; |
||
264 | var handler = controls[focus_section][0]; |
||
265 | var keyHandler; |
||
266 | switch (charStr) { |
||
267 | case "1": // select section 1 |
||
268 | case "2": // select section 2 |
||
269 | case "3": // select section 3 |
||
270 | case "4": // select section 4 |
||
271 | focus_section = charStr; |
||
272 | break; |
||
273 | case "+": // zoom in |
||
274 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'zoomin')); |
||
275 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
276 | break; |
||
277 | case "-": // zoom out |
||
278 | keyHandler = encodeURIComponent(getHandlerCommand(handler, 'zoomout')); |
||
279 | sendToNuc('window=' + section + '&key=' + keyHandler); |
||
280 | break; |
||
281 | } |
||
282 | }; |
||
283 | |||
284 | var windowlist = document.getElementById('windowlist'); |
||
285 | var entries = windowlist.getElementsByClassName('window_entry'); |
||
286 | var screensection, file, status; |
||
287 | markCurrentLayout(layout); |
||
288 | for (var n = 0; n < window.length; n++) { |
||
289 | screensection = window[n].section; |
||
290 | file = window[n].file; |
||
291 | status = window[n].state; |
||
292 | entries[n].appendChild(addWindowControls(layout, controls, screensection, file, status)); |
||
293 | } |
||
294 | } |
||
295 | |||
296 | function markCurrentLayout(layout) { |
||
297 | var layoutDivs = document.getElementsByClassName("screenlayout"); |
||
298 | for (var i = 0 ; i < layoutDivs.length ; i++) { |
||
299 | var children = layoutDivs[i].getElementsByClassName("pure-button"); |
||
300 | for (var k = 0 ; k < children.length ; k++) { |
||
301 | children[k].style.backgroundColor = ""; |
||
302 | } |
||
303 | } |
||
304 | document.getElementById(layout).style.backgroundColor = "#232e58"; |
||
305 | } |
||
306 | |||
307 | function miniDisplaySelect(element) { |
||
308 | sendToNuc('layout=' + element.id); |
||
309 | markCurrentLayout(element.id); |
||
310 | } |
||
311 | |||
312 | function getHandlerCommand(handle, task) { |
||
313 | |||
314 | // console.log("getHandlerCommand "+handle+" - "+task); |
||
315 | // to deactivate buttons just add 'undefined' as keystroke |
||
316 | |||
317 | var handler = []; |
||
318 | |||
319 | handler["default"] = {}; |
||
320 | // handler["default"]["init"] = ""; |
||
321 | handler["default"]["up"] = "Up"; |
||
322 | handler["default"]["down"] = "Down"; |
||
323 | handler["default"]["left"] = "Left"; |
||
324 | handler["default"]["right"] = "Right"; |
||
325 | handler["default"]["next"] = "Next"; |
||
326 | handler["default"]["prior"] = "Prior"; |
||
327 | handler["default"]["home"] = "Home"; |
||
328 | handler["default"]["end"] = "End"; |
||
329 | handler["default"]["zoomin"] = "ctrl+plus"; |
||
330 | handler["default"]["zoomout"] = "ctrl+minus"; |
||
331 | handler["default"]["download"] = "download"; |
||
332 | handler["default"]["counterclockwise"] = "undefined"; |
||
333 | handler["default"]["clockwise"] = "undefined"; |
||
334 | |||
335 | // Handler for web pages. |
||
336 | handler["palma-browser"] = {}; |
||
337 | handler["palma-browser"]["up"] = "Up"; |
||
338 | handler["palma-browser"]["down"] = "Down"; |
||
339 | handler["palma-browser"]["left"] = "Left"; |
||
340 | handler["palma-browser"]["right"] = "Right"; |
||
341 | handler["palma-browser"]["next"] = "Next"; |
||
342 | handler["palma-browser"]["prior"] = "Prior"; |
||
343 | handler["palma-browser"]["home"] = "Home"; |
||
344 | handler["palma-browser"]["end"] = "End"; |
||
345 | handler["palma-browser"]["zoomin"] = "ctrl+plus"; |
||
346 | handler["palma-browser"]["zoomout"] = "ctrl+minus"; |
||
347 | handler["palma-browser"]["download"] = "undefined"; |
||
348 | handler["palma-browser"]["counterclockwise"] = "undefined"; |
||
349 | handler["palma-browser"]["clockwise"] = "undefined"; |
||
350 | |||
351 | // Handler for images. |
||
352 | handler["feh"] = {}; |
||
353 | handler["feh"]["up"] = "alt+Up"; |
||
354 | handler["feh"]["down"] = "alt+Down"; |
||
355 | handler["feh"]["left"] = "alt+Left"; |
||
356 | handler["feh"]["right"] = "alt+Right"; |
||
357 | handler["feh"]["next"] = "alt+Next"; |
||
358 | handler["feh"]["prior"] = "alt+Prior"; |
||
359 | handler["feh"]["home"] = "undefined"; |
||
360 | handler["feh"]["end"] = "undefined"; |
||
361 | handler["feh"]["zoomin"] = "KP_Add"; |
||
362 | handler["feh"]["zoomout"] = "KP_Subtract"; |
||
363 | handler["feh"]["download"] = "download"; |
||
364 | handler["feh"]["counterclockwise"] = "less"; |
||
365 | handler["feh"]["clockwise"] = "greater"; |
||
366 | |||
367 | // Controls in LibreOffice: no zoom in calc and writer, has to be activated first |
||
368 | // by pressing <Ctrl+Shift+o> (switch view mode on/off) not implemented yet |
||
369 | handler["libreoffice"] = {}; |
||
370 | handler["libreoffice"]["up"] = "Up"; |
||
371 | handler["libreoffice"]["down"] = "Down"; |
||
372 | handler["libreoffice"]["left"] = "Left"; |
||
373 | handler["libreoffice"]["right"] = "Right"; |
||
374 | handler["libreoffice"]["next"] = "Next"; |
||
375 | handler["libreoffice"]["prior"] = "Prior"; |
||
376 | handler["libreoffice"]["home"] = "undefined"; |
||
377 | handler["libreoffice"]["end"] = "undefined"; |
||
378 | handler["libreoffice"]["zoomin"] = "undefined"; |
||
379 | handler["libreoffice"]["zoomout"] = "undefined"; |
||
380 | handler["libreoffice"]["download"] = "download"; |
||
381 | handler["libreoffice"]["counterclockwise"] = "undefined"; |
||
382 | handler["libreoffice"]["clockwise"] = "undefined"; |
||
383 | |||
384 | // Handler for MS Excel and LibreOffice Calc documents. |
||
385 | handler["libreoffice-calc"] = {}; |
||
386 | handler["libreoffice-calc"]["up"] = "Up"; |
||
387 | handler["libreoffice-calc"]["down"] = "Down"; |
||
388 | handler["libreoffice-calc"]["left"] = "Left"; |
||
389 | handler["libreoffice-calc"]["right"] = "Right"; |
||
390 | handler["libreoffice-calc"]["next"] = "Next"; |
||
391 | handler["libreoffice-calc"]["prior"] = "Prior"; |
||
392 | handler["libreoffice-calc"]["home"] = "Home"; |
||
393 | handler["libreoffice-calc"]["end"] = "End"; |
||
394 | handler["libreoffice-calc"]["zoomin"] = "undefined"; |
||
395 | handler["libreoffice-calc"]["zoomout"] = "undefined"; |
||
396 | handler["libreoffice-calc"]["download"] = "download"; |
||
397 | handler["libreoffice-calc"]["counterclockwise"] = "undefined"; |
||
398 | handler["libreoffice-calc"]["clockwise"] = "undefined"; |
||
399 | |||
400 | // Handler for MS Powerpoint and LibreOffice Impress documents. |
||
401 | handler["libreoffice-impress"] = {}; |
||
402 | handler["libreoffice-impress"]["up"] = "Up"; |
||
403 | handler["libreoffice-impress"]["down"] = "Down"; |
||
404 | handler["libreoffice-impress"]["left"] = "Left"; |
||
405 | handler["libreoffice-impress"]["right"] = "Right"; |
||
406 | handler["libreoffice-impress"]["next"] = "Next"; |
||
407 | handler["libreoffice-impress"]["prior"] = "Prior"; |
||
408 | handler["libreoffice-impress"]["home"] = "Home"; |
||
409 | handler["libreoffice-impress"]["end"] = "End"; |
||
410 | handler["libreoffice-impress"]["zoomin"] = "plus"; |
||
411 | handler["libreoffice-impress"]["zoomout"] = "minus"; |
||
412 | handler["libreoffice-impress"]["download"] = "download"; |
||
413 | handler["libreoffice-impress"]["counterclockwise"] = "undefined"; |
||
414 | handler["libreoffice-impress"]["clockwise"] = "undefined"; |
||
415 | |||
416 | // Handler for MS Word and LibreOffice Writer documents. |
||
417 | handler["libreoffice-writer"] = {}; |
||
418 | handler["libreoffice-writer"]["up"] = "Up"; |
||
419 | handler["libreoffice-writer"]["down"] = "Down"; |
||
420 | handler["libreoffice-writer"]["left"] = "Left"; |
||
421 | handler["libreoffice-writer"]["right"] = "Right"; |
||
422 | handler["libreoffice-writer"]["next"] = "Next"; |
||
423 | handler["libreoffice-writer"]["prior"] = "Prior"; |
||
424 | handler["libreoffice-writer"]["home"] = "undefined"; |
||
425 | handler["libreoffice-writer"]["end"] = "undefined"; |
||
426 | handler["libreoffice-writer"]["zoomin"] = "undefined"; |
||
427 | handler["libreoffice-writer"]["zoomout"] = "undefined"; |
||
428 | handler["libreoffice-writer"]["download"] = "download"; |
||
429 | handler["libreoffice-writer"]["counterclockwise"] = "undefined"; |
||
430 | handler["libreoffice-writer"]["clockwise"] = "undefined"; |
||
431 | |||
432 | // Handler for videos. |
||
433 | handler["vlc"] = {}; |
||
434 | handler["vlc"]["up"] = "undefined"; |
||
435 | handler["vlc"]["down"] = "undefined"; |
||
436 | handler["vlc"]["left"] = "undefined"; |
||
437 | handler["vlc"]["right"] = "space"; |
||
438 | handler["vlc"]["next"] = "undefined"; |
||
439 | handler["vlc"]["prior"] = "undefined"; |
||
440 | handler["vlc"]["home"] = "undefined"; |
||
441 | handler["vlc"]["end"] = "undefined"; |
||
442 | handler["vlc"]["zoomin"] = "undefined"; |
||
443 | handler["vlc"]["zoomout"] = "undefined"; |
||
444 | handler["vlc"]["download"] = "undefined"; |
||
445 | handler["vlc"]["counterclockwise"] = "undefined"; |
||
446 | handler["vlc"]["clockwise"] = "undefined"; |
||
447 | |||
448 | // Handler for shared desktops (VNC). |
||
449 | handler["vnc"] = {}; |
||
450 | handler["vnc"]["up"] = "Up"; |
||
451 | handler["vnc"]["down"] = "Down"; |
||
452 | handler["vnc"]["left"] = "Left"; |
||
453 | handler["vnc"]["right"] = "Right"; |
||
454 | handler["vnc"]["next"] = "undefined"; |
||
455 | handler["vnc"]["prior"] = "undefined"; |
||
456 | handler["vnc"]["home"] = "undefined"; |
||
457 | handler["vnc"]["end"] = "undefined"; |
||
458 | handler["vnc"]["zoomin"] = "plus"; |
||
459 | handler["vnc"]["zoomout"] = "minus"; |
||
460 | handler["vnc"]["download"] = "undefined"; |
||
461 | handler["vnc"]["counterclockwise"] = "undefined"; |
||
462 | handler["vnc"]["clockwise"] = "undefined"; |
||
463 | |||
464 | // Handler for PDF documents. |
||
465 | handler["zathura"] = {}; |
||
466 | handler["zathura"]["up"] = "Up"; |
||
467 | handler["zathura"]["down"] = "Down"; |
||
468 | handler["zathura"]["left"] = "Left"; |
||
469 | handler["zathura"]["right"] = "Right"; |
||
470 | handler["zathura"]["next"] = "Next"; |
||
471 | handler["zathura"]["prior"] = "Prior"; |
||
472 | handler["zathura"]["home"] = "Home"; |
||
473 | handler["zathura"]["end"] = "End"; |
||
474 | handler["zathura"]["zoomin"] = "plus"; |
||
475 | handler["zathura"]["zoomout"] = "minus"; |
||
476 | handler["zathura"]["download"] = "download"; |
||
477 | handler["zathura"]["counterclockwise"] = "undefined"; |
||
478 | handler["zathura"]["clockwise"] = "r"; |
||
479 | |||
480 | var send_keys = handler["default"]["up"]; |
||
481 | |||
482 | if (typeof(handler[handle]) !== "undefined") { |
||
483 | send_keys = handler[handle][task]; |
||
484 | } |
||
485 | |||
486 | // console.log(send_keys); |
||
487 | |||
488 | return send_keys; |
||
489 | } |
||
490 | |||
491 | Dropzone.options.palmaDropzone = { |
||
492 | init: function() { |
||
493 | this.on("complete", function() { |
||
494 | if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0) { |
||
495 | // File finished uploading, and there aren't any left in the queue. |
||
496 | // console.log("File(s) uploaded"); |
||
497 | setTimeout(function() { |
||
498 | location.reload(); |
||
499 | }, 1); |
||
500 | // location.reload(); // verlangt Eingabe von Enter zum wiederholten Schicken der Daten |
||
501 | } |
||
502 | }); |
||
503 | } |
||
504 | }; |
||
505 | |||
506 | function updateUserList(address, user) { |
||
507 | // Update the user list on screen from the table in the database. |
||
508 | |||
509 | // Get the <tbody> element which contains the user entries. |
||
510 | var list = document.getElementById('userlist'); |
||
511 | |||
512 | // First we remove all existing <tr> elements. |
||
513 | while (list.firstChild) { |
||
514 | list.removeChild(list.firstChild); |
||
515 | } |
||
516 | |||
517 | if (address.length > 0) { |
||
518 | // Add an entry for each user. Iterate over addresses: |
||
519 | // One user may be connected several times with different devices. |
||
520 | // We don't expect more than one user from the same device. |
||
521 | var m; |
||
522 | for (m = 0; m < address.length; m++) { |
||
523 | var n; |
||
524 | for (n = 0; n < user.length; n++) { |
||
525 | if (address[m].userid == user[n].userid) { |
||
526 | break; |
||
527 | } |
||
528 | } |
||
529 | var device = address[m].device; |
||
530 | var tr = document.createElement('tr'); |
||
531 | var td = document.createElement('td'); |
||
532 | var i = document.createElement('i'); |
||
533 | i.setAttribute('class', 'fa fa-fw fa-' + device); |
||
534 | td.appendChild(i); |
||
535 | td.appendChild(document.createTextNode(user[n].name)); |
||
536 | tr.appendChild(td); |
||
537 | list.appendChild(tr); |
||
538 | } |
||
539 | } else { |
||
540 | <?php |
||
541 | if ($user) { |
||
542 | ?> |
||
543 | // All users were disconnected. |
||
544 | alert("<?=addslashes(__('You were disconnected!'))?>"); |
||
545 | window.location = 'logout.php'; |
||
546 | <?php |
||
547 | } else { |
||
548 | ?> |
||
549 | // If there is no user, we display an empty entry. |
||
550 | var tr = document.createElement('tr'); |
||
551 | var td = document.createElement('td'); |
||
552 | td.appendChild(document.createTextNode("\u00a0")); |
||
553 | tr.appendChild(td); |
||
554 | list.appendChild(tr); |
||
555 | <?php |
||
556 | } |
||
557 | ?> |
||
558 | } |
||
559 | } |
||
560 | |||
561 | |||
562 | function addWindowPosition(layout, screensection) { |
||
563 | var position = document.createElement("div"); |
||
564 | position.setAttribute("class", "position " + layout); |
||
565 | position.setAttribute('title', '<?=addslashes(__("Select screen section for display"))?>'); |
||
566 | |||
567 | var s; |
||
568 | var button; |
||
569 | var icon; |
||
570 | var br; |
||
571 | |||
572 | switch (layout) { |
||
573 | case 'g1x1': |
||
574 | s = 1; |
||
575 | break; |
||
576 | case 'g1x2': |
||
577 | s = 2; |
||
578 | break; |
||
579 | case 'g2x1': |
||
580 | s = 2; |
||
581 | break; |
||
582 | case 'g1a2': |
||
583 | s = 3; |
||
584 | var layout_left = document.createElement('div'); |
||
585 | layout_left.setAttribute("class", "layout_left"); |
||
586 | var layout_right = document.createElement('div'); |
||
587 | layout_right.setAttribute("class", "layout_right"); |
||
588 | break; |
||
589 | case 'g2x2': |
||
590 | s = 4; |
||
591 | break; |
||
592 | } |
||
593 | |||
594 | for (var n = 1; n <= s; n++) { |
||
595 | br = ''; |
||
596 | button = document.createElement("button"); |
||
597 | button.setAttribute('value', n); |
||
598 | if (n == screensection) { |
||
599 | button.setAttribute("class", "selected"); |
||
600 | } |
||
601 | button.setAttribute('onclick', "sendToNuc('switchWindows=TRUE&before=" + screensection + "&after='+(this.value))"); |
||
602 | icon = document.createElement("i"); |
||
603 | if (s == 1) { |
||
604 | icon.setAttribute("class", "fa fa-desktop fa-2x"); |
||
605 | } else { |
||
606 | icon.setAttribute("class", "fa fa-desktop fa-1x"); |
||
607 | } |
||
608 | button.appendChild(icon); |
||
609 | |||
610 | if ((layout == 'g1x2' && n == 1) || ((layout == 'g1a2' || layout == 'g2x2') && n == 2 )) { |
||
611 | br = document.createElement("br"); |
||
612 | } |
||
613 | |||
614 | if (layout == 'g1a2' && n == 1) { |
||
615 | layout_left.appendChild(button); |
||
616 | } else if (layout == 'g1a2' && n > 1) { |
||
617 | layout_right.appendChild(button); |
||
618 | if (br) { |
||
619 | layout_right.appendChild(br); |
||
620 | } |
||
621 | } else { |
||
622 | position.appendChild(button); |
||
623 | if (br) { |
||
624 | position.appendChild(br); |
||
625 | } |
||
626 | } |
||
627 | } |
||
628 | |||
629 | if (layout == 'g1a2') { |
||
630 | position.appendChild(layout_left); |
||
631 | position.appendChild(layout_right); |
||
632 | } |
||
633 | return position; |
||
634 | } |
||
635 | |||
636 | |||
637 | function addWindowControls(layout, controls, screensection, file, status) { |
||
638 | var control = controls[screensection]; |
||
639 | if (typeof control == "undefined") { |
||
640 | control = ["default", false, false, false, false, |
||
641 | false, false, false, false, false, false, false]; |
||
642 | } |
||
643 | |||
644 | // get handler |
||
645 | var handler = control[0]; |
||
646 | // up down left right zoomin zoomout home end prior next download |
||
647 | var up = control[1]; |
||
648 | var down = control[2]; |
||
649 | var left = control[3]; |
||
650 | var right = control[4]; |
||
651 | var zoomin = control[5]; |
||
652 | var zoomout = control[6]; |
||
653 | var home = control[7]; |
||
654 | var end = control[8]; |
||
655 | var prior = control[9]; |
||
656 | var next = control[10]; |
||
657 | var download = control[11]; |
||
658 | var counterclockwise = control[12]; |
||
659 | var clockwise = control[13]; |
||
660 | |||
661 | var windowcontrols = document.createElement("div"); |
||
662 | windowcontrols.setAttribute("class", "windowcontrols"); |
||
663 | |||
664 | var topbar = document.createElement("div"); |
||
665 | topbar.setAttribute("class", "topbar"); |
||
666 | var button = document.createElement('button'); |
||
667 | button.setAttribute("class", "toggle"); |
||
668 | icon = document.createElement('i'); |
||
669 | if (status == 'active') { |
||
670 | icon.setAttribute("class", "fa fa-eye"); |
||
671 | } else { |
||
672 | icon.setAttribute("class", "fa fa-eye-slash"); |
||
673 | } |
||
674 | icon.setAttribute('id', 'status_' + screensection); |
||
675 | button.setAttribute('title', '<?=addslashes(__("Toggle visibility"))?>'); |
||
676 | button.setAttribute('onclick', "sendToNuc('window=" + screensection + "&toggle=TRUE')"); |
||
677 | button.appendChild(icon); |
||
678 | topbar.appendChild(button); |
||
679 | topbar.appendChild(keyControl(screensection, 'fa fa-search-plus', 'zoomin', 'zoomin', handler, !zoomin, '<?=addslashes(__("Zoom in"))?>')); |
||
680 | topbar.appendChild(keyControl(screensection, 'fa fa-search-minus', 'zoomout', 'zoomout', handler, !zoomout, '<?=addslashes(__("Zoom out"))?>')); |
||
681 | topbar.appendChild(keyControl(screensection, 'fa fa-rotate-left', 'counterclockwise', 'counterclockwise', handler, !counterclockwise, '<?=addslashes(__("Rotate counterclockwise"))?>')); |
||
682 | topbar.appendChild(keyControl(screensection, 'fa fa-rotate-right', 'clockwise', 'clockwise', handler, !clockwise, '<?=addslashes(__("Rotate clockwise"))?>')); |
||
683 | var downloadbutton = keyControl(screensection, 'fa fa-download', 'download', 'download', handler, !download, '<?=addslashes(__("Download this item"))?>'); |
||
684 | if(download) { |
||
685 | downloadbutton.setAttribute('onclick', 'downloadFile(' + screensection + ')'); |
||
686 | } |
||
687 | topbar.appendChild(downloadbutton); |
||
688 | button = document.createElement('button'); |
||
689 | button.setAttribute("class", "trash"); |
||
690 | button.setAttribute('onclick', "sendToNuc('window=" + screensection + "&delete=" + file + "')"); |
||
691 | button.setAttribute('title', '<?=addslashes(__("Remove this item"))?>'); |
||
692 | icon = document.createElement('i'); |
||
693 | icon.setAttribute("class", "fa fa-trash-o"); |
||
694 | button.appendChild(icon); |
||
695 | topbar.appendChild(button); |
||
696 | |||
697 | var movement = document.createElement("div"); |
||
698 | movement.setAttribute("class", "movement"); |
||
699 | |||
700 | var jump = document.createElement("div"); |
||
701 | jump.setAttribute("class", "jump"); |
||
702 | jump.appendChild(keyControl(screensection, 'fa fa-angle-double-up', 'jumpbeginning', 'home', handler, !home, '<?=addslashes(__("Jump to start"))?>')); |
||
703 | jump.appendChild(keyControl(screensection, 'fa fa-angle-up', 'pageback', 'prior', handler, !prior, '<?=addslashes(__("Page up"))?>')); |
||
704 | jump.appendChild(keyControl(screensection, 'fa fa-angle-down', 'pageforward', 'next', handler, !next, '<?=addslashes(__("Page down"))?>')); |
||
705 | jump.appendChild(keyControl(screensection, 'fa fa-angle-double-down', 'jumpend', 'end', handler, !end, '<?=addslashes(__("Jump to end"))?>')); |
||
706 | |||
707 | var arrows = document.createElement("div"); |
||
708 | arrows.setAttribute("class", "arrows"); |
||
709 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-up', 'arrowup', 'up', handler, !up, '<?=addslashes(__("Up"))?>')); |
||
710 | arrows.appendChild(document.createElement("br")); |
||
711 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-left', 'arrowleft', 'left', handler, !left, '<?=addslashes(__("Left"))?>')); |
||
712 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-right', 'arrowright', 'right', handler, !right, '<?=addslashes(__("Right"))?>')); |
||
713 | arrows.appendChild(document.createElement("br")); |
||
714 | arrows.appendChild(keyControl(screensection, 'fa fa-toggle-down', 'arrowdown', 'down', handler, !down, '<?=addslashes(__("Down"))?>')); |
||
715 | |||
716 | movement.appendChild(jump); |
||
717 | movement.appendChild(arrows); |
||
718 | |||
719 | var position = addWindowPosition(layout, screensection); |
||
720 | |||
721 | // Putting it all together |
||
722 | windowcontrols.appendChild(topbar); |
||
723 | windowcontrols.appendChild(movement); |
||
724 | windowcontrols.appendChild(position); |
||
725 | return windowcontrols; |
||
726 | } |
||
727 | |||
728 | |||
729 | function updateWindowList(window){ |
||
730 | var windowlist = document.getElementById('windowlist'); |
||
731 | // remove old entries |
||
732 | while (windowlist.firstChild) { |
||
733 | windowlist.removeChild(windowlist.firstChild); |
||
734 | } |
||
735 | |||
736 | if (window.length == 0) { |
||
737 | var entry = document.createElement('div'); |
||
738 | entry.setAttribute("class", "description"); |
||
739 | entry.appendChild(document.createTextNode('<?=addslashes(__('Welcome'))?>, <?=htmlspecialchars($username)?>!')); |
||
740 | entry.appendChild(document.createElement("br")); |
||
741 | entry.appendChild(document.createTextNode('<?=addslashes(__('There is no shared content yet. Click below to get started!'))?>')); |
||
742 | var addbutton = document.createElement('button'); |
||
743 | addbutton.setAttribute("class", "splash_add pure-button"); |
||
744 | addbutton.setAttribute("onclick", "openTab(event, 'Add')"); |
||
745 | var addtext = (document.createTextNode('<?=addslashes(__("Add"))?>')); |
||
746 | addbutton.appendChild(addtext); |
||
747 | var addicon = document.createElement("i"); |
||
748 | addicon.setAttribute("class", "fa fa-plus"); |
||
749 | addbutton.appendChild(addicon); |
||
750 | windowlist.appendChild(entry); |
||
751 | windowlist.appendChild(addbutton); |
||
752 | document.getElementById("closeWindows").style.display = "none"; |
||
753 | document.getElementById("Layout").style.display = "none"; |
||
754 | document.getElementById("controlbtn").className = "tablinks"; |
||
755 | } else { |
||
756 | document.getElementById("closeWindows").style.display = "inline-block"; |
||
757 | document.getElementById("Layout").style.display = "block"; |
||
758 | document.getElementById("controlbtn").className = "tablinks active"; |
||
759 | // Add an entry for each window. |
||
760 | var n; |
||
761 | for (n = 0; n < window.length; n++) { |
||
762 | var file = window[n].file; |
||
763 | var handler = window[n].handler; |
||
764 | var screensection = window[n].section; |
||
765 | var entry = document.createElement('div'); |
||
766 | entry.setAttribute("class", "window_entry"); |
||
767 | var divID = 'file' + screensection; |
||
768 | entry.setAttribute('id', divID); |
||
769 | |||
770 | var button = document.createElement('button'); |
||
771 | button.setAttribute("class", "window_entry_button"); |
||
772 | button.setAttribute('onclick', "openAccordion('" + divID + "')"); |
||
773 | var icon = document.createElement('i'); |
||
774 | if (handler.indexOf("palma-browser") > -1) { |
||
775 | icon.setAttribute("class", "fa fa-globe"); |
||
776 | } else if (handler.indexOf("vnc") > -1) { |
||
777 | icon.setAttribute("class", "fa fa-video-camera"); |
||
778 | } else if (handler.indexOf("vlc") > -1) { |
||
779 | icon.setAttribute("class", "fa fa-film"); |
||
780 | } else if (handler.indexOf("feh") > -1) { |
||
781 | icon.setAttribute("class", "fa fa-picture-o"); |
||
782 | } else if (handler.indexOf("zathura") > -1) { |
||
783 | icon.setAttribute("class", "fa fa-file-pdf-o"); |
||
784 | } else { |
||
785 | icon.setAttribute("class", "fa fa-file"); |
||
786 | } |
||
787 | button.appendChild(icon); |
||
788 | var title = decodeURI(decodeURIComponent(file)); |
||
789 | // display only the last part of the URL or file name. |
||
790 | // Long names are truncated, and the truncation is indicated. |
||
791 | if (title.substring(0, 4) == 'http') { |
||
792 | // Remove a terminating slash from an URL. |
||
793 | // The full URL will be shown as a tooltip. |
||
794 | title = title.replace(/\/$/, ''); |
||
795 | title = title.replace(/^.*\//, ''); |
||
796 | entry.setAttribute('title', file); |
||
797 | } else { |
||
798 | // For files only the full base name is shown as a tooltip. |
||
799 | var fname = file; |
||
800 | title = title.replace(/^.*\//, ''); |
||
801 | entry.setAttribute('title', fname); |
||
802 | } |
||
803 | if (title.length > 25) { |
||
804 | title = title.substring(0, 25) + '...'; |
||
805 | } |
||
806 | button.appendChild(document.createTextNode(title)); |
||
807 | var icon = document.createElement('i'); |
||
808 | icon.setAttribute("class", "fa fa-caret-down accordion-icon"); |
||
809 | button.appendChild(icon); |
||
810 | entry.appendChild(button); |
||
811 | windowlist.appendChild(entry); |
||
812 | } |
||
813 | } |
||
814 | } |
||
815 | |||
816 | function updateControlsBySection(window) { |
||
817 | |||
818 | // get section and handler for each window |
||
819 | var sectionControls = []; |
||
820 | |||
821 | for (n = 0; n < window.length; n++) { |
||
822 | var win_id = window[n].win_id; |
||
823 | var section = window[n].section; |
||
824 | var handler = window[n].handler; |
||
825 | |||
826 | // alert("Section: " + section + " - Handler: " + handler); |
||
827 | |||
828 | if (handler.indexOf("feh") > -1) { |
||
829 | // up down left right zoomin zoomout home end prior next download rotateleft rotateright |
||
830 | control = ["feh", true, true, true, true, true, true, false, false, false, false, true, true, true]; |
||
831 | } else if (handler.indexOf("libreoffice") > -1) { |
||
832 | // Controls in LibreOffice: no zoom in calc and writer, has to be activated first |
||
833 | // by pressing <Ctrl+Shift+o> (switch view mode on/off) not implemented yet |
||
834 | control = ["libreoffice", true, true, true, true, false, false, false, false, true, true, true, false, false]; |
||
835 | if (handler.indexOf("--calc") > -1) { |
||
836 | control = ["libreoffice-calc", true, true, true, true, false, false, true, true, true, true, true, false, false]; |
||
837 | } |
||
838 | if (handler.indexOf("--impress") > -1) { |
||
839 | control = ["libreoffice-impress", true, true, true, true, true, true, true, true, true, true, true, false, false]; |
||
840 | } |
||
841 | if (handler.indexOf("--writer") > -1) { |
||
842 | control = ["libreoffice-writer", true, true, true, true, false, false, false, false, true, true, true, false, false]; |
||
843 | } |
||
844 | } else if (handler.indexOf("palma-browser") > -1) { |
||
845 | control = ["palma-browser", true, true, true, true, true, true, true, true, true, true, false, false, false]; |
||
846 | } else if (handler.indexOf("vlc") > -1) { |
||
847 | control = ["vlc", false, false, false, true, false, false, false, false, false, false, false, false, false]; |
||
848 | } else if (handler.indexOf("vnc") > -1) { |
||
849 | control = ["vnc", true, true, true, true, true, true, false, false, false, false, false, false, false]; |
||
850 | } else if (handler.indexOf("zathura") > -1) { |
||
851 | control = ["zathura", true, true, true, true, true, true, true, true, true, true, true, false, true]; |
||
852 | } else { |
||
853 | control = ["undefined", false, false, false, false, false, false, false, false, false, false, false, false, false]; |
||
854 | } |
||
855 | |||
856 | sectionControls[section] = control; |
||
857 | } |
||
858 | |||
859 | // Fill empty sections with default values. |
||
860 | for (i = sectionControls.length; i < 5; i++) { |
||
861 | sectionControls[i] = ["default", |
||
862 | false, false, false, false, |
||
863 | false, false, false, false, |
||
864 | false, false, false, false, false]; |
||
865 | } |
||
866 | |||
867 | return sectionControls; |
||
868 | } |
||
869 | |||
870 | function updateScreen() { |
||
871 | sendToNuc('window=all&closeOrphans=true'); |
||
872 | } |
||
873 | |||
874 | function clearURLField(defaultText) { |
||
875 | var browseto = document.getElementById('url_field'); |
||
876 | browseto.setAttribute('value', 'https://'); |
||
877 | } |
||
878 | |||
879 | // lastJSON is used to reduce the database polling rate. |
||
880 | var lastJSON = ''; |
||
881 | |||
882 | function pollDatabase() { |
||
883 | var xmlHttp = new XMLHttpRequest(); |
||
884 | if (xmlHttp) { |
||
885 | xmlHttp.open("get", 'db.php?json=' + lastJSON, true); |
||
886 | xmlHttp.onreadystatechange = function () { |
||
887 | if (xmlHttp.readyState == 2) { |
||
888 | // Data transferred to server. |
||
889 | } else if (xmlHttp.readyState == 3) { |
||
890 | // Server is answering. |
||
891 | } else if (xmlHttp.readyState == 4) { |
||
892 | // Received all data from server. |
||
893 | var status = xmlHttp.status; |
||
894 | if (status == 200) { |
||
895 | // Got valid response. |
||
896 | var text = xmlHttp.responseText; |
||
897 | lastJSON = text; |
||
898 | var db = JSON.parse(text); |
||
899 | var i; |
||
900 | var layout = ''; |
||
901 | for (i = 0; i < db.setting.length; i++) { |
||
902 | if (db.setting[i].key == 'layout') { |
||
903 | layout = db.setting[i].value; |
||
904 | break; |
||
905 | } |
||
906 | } |
||
907 | var controls = updateControlsBySection(db.window); |
||
908 | // for (i = 0; i < controls.length; i++) { |
||
909 | // console.log(i + ": " + controls[i]); |
||
910 | // } |
||
911 | updateUserList(db.address, db.user); |
||
912 | updateWindowList(db.window); |
||
913 | showLayout(layout, controls, db.window); |
||
914 | // updateScreen(db.window); |
||
915 | setTimeout("pollDatabase()", 1); |
||
916 | } else { |
||
917 | // Got error. TODO: handle it. |
||
918 | } |
||
919 | } else { |
||
920 | // Got unexpected xmlHttp.readyState. TODO: handle it. |
||
921 | } |
||
922 | }; |
||
923 | xmlHttp.send(null); |
||
924 | } |
||
925 | } |
||
926 | |||
927 | // Start polling the database. |
||
928 | pollDatabase(); |
||
929 | |||
930 | |||
931 | function getOS() { |
||
932 | var OSName="Unknown OS"; |
||
933 | if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows"; |
||
934 | if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS"; |
||
935 | if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX"; |
||
936 | if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux"; |
||
937 | if (navigator.userAgent.indexOf("Android")!=-1) OSName="Android"; |
||
938 | if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) OSName="iOS"; |
||
939 | /* Source for Android and iOS: |
||
940 | https://davidwalsh.name/detect-android |
||
941 | https://davidwalsh.name/detect-iphone |
||
942 | https://davidwalsh.name/detect-ipad */ |
||
943 | return OSName; |
||
944 | } |
||
945 | |||
946 | function getFilePathByOS() { |
||
947 | var OSName = getOS(); |
||
948 | var windows = 'download-winvnc'; |
||
949 | var macOS = 'download-macvnc'; |
||
950 | var linux = 'download-linux'; |
||
951 | var download = ''; |
||
952 | switch(OSName) { |
||
953 | case 'Windows': download = windows; |
||
954 | break; |
||
955 | case 'MacOS': download = macOS; |
||
956 | break; |
||
957 | case 'Linux': download = linux; |
||
958 | break; |
||
959 | case 'UNIX': download = linux; |
||
960 | break; |
||
961 | case 'Android': |
||
962 | case 'iOS': |
||
963 | document.getElementById("Screen").innerHTML = '<div class="description"><?=addslashes(__('Sorry! Screensharing for your device is currently not supported.'))?></div>'; |
||
964 | break; |
||
965 | default: download = null; |
||
966 | } |
||
967 | document.getElementById(download).click(); |
||
968 | } |
||
969 | |||
970 | function openTab(evt, tabName) { |
||
971 | var i, tabcontent, tablinks; |
||
972 | // Hide all elements with class="tabcontent" |
||
973 | tabcontent = document.getElementsByClassName("tabcontent"); |
||
974 | for (i = 0; i < tabcontent.length; i++) { |
||
975 | tabcontent[i].style.display = "none"; |
||
976 | } |
||
977 | // Remove "active" class from all elements with class="tablinks" |
||
978 | tablinks = document.getElementsByClassName("tablinks"); |
||
979 | for (i = 0; i < tablinks.length; i++) { |
||
980 | tablinks[i].className = tablinks[i].className.replace(" active", ""); |
||
981 | } |
||
982 | |||
983 | // Show current tab and add "active" class to the opening button |
||
984 | document.getElementById(tabName).style.display = "block"; |
||
985 | evt.currentTarget.className += " active"; |
||
986 | } |
||
987 | |||
988 | function openSubtab(evt, tabName, subtabName) { |
||
989 | var i, tab, subtabcontent, subtablinks; |
||
990 | // Hide all elements with class="subtabcontent" |
||
991 | tab = document.getElementById(tabName); |
||
992 | subtabcontent = tab.getElementsByClassName("subtabcontent"); |
||
993 | for (i = 0; i < subtabcontent.length; i++) { |
||
994 | subtabcontent[i].style.display = "none"; |
||
995 | } |
||
996 | |||
997 | // Remove "active" class from all elements with class="subtablinks" |
||
998 | subtablinks = tab.getElementsByClassName("subtablinks"); |
||
999 | for (i = 0; i < subtablinks.length; i++) { |
||
1000 | subtablinks[i].className = subtablinks[i].className.replace(" active", ""); |
||
1001 | } |
||
1002 | |||
1003 | // Show current subtab and add "active" class to the opening button |
||
1004 | document.getElementById(subtabName).style.display = "block"; |
||
1005 | evt.currentTarget.className += " active"; |
||
1006 | } |
||
1007 | |||
1008 | function openAccordion(divID) { |
||
1009 | var button = document.getElementById(divID).firstChild; |
||
1010 | var windowcontrols = document.getElementById(divID).lastChild; |
||
1011 | if (windowcontrols.style.display == "block") { |
||
1012 | windowcontrols.style.display = "none"; |
||
1013 | button.setAttribute("class", "window_entry_button"); |
||
1014 | } else if (windowcontrols.style.display == "none") { |
||
1015 | windowcontrols.style.display = "block"; |
||
1016 | button.setAttribute("class", "window_entry_button active"); |
||
1017 | } else { |
||
1018 | windowcontrols.style.display = "block"; |
||
1019 | button.setAttribute("class", "window_entry_button active"); |
||
1020 | } |
||
1021 | } |
||
1022 | |||
1023 | function showDropdown() { |
||
1024 | document.getElementById("languageSelection").classList.toggle("show"); |
||
1025 | } |
||
1026 | // Close the dropdown menu if the user clicks outside of it |
||
1027 | // Must use some workaround to support IE. |
||
1028 | window.onclick = function(event) { |
||
1029 | var classes = event.target.className.split(' '); |
||
1030 | var found = false; var i = 0; |
||
1031 | while (i < classes.length && !found) { |
||
1032 | if (classes[i]=='dropbutton') found = true; |
||
1033 | else ++i; |
||
1034 | } |
||
1035 | if (!found) { |
||
1036 | var dropdowns = document.getElementsByClassName("dropdown-content"); |
||
1037 | var i; |
||
1038 | for (i = 0; i < dropdowns.length; i++) { |
||
1039 | var openDropdown = dropdowns[i]; |
||
1040 | if (openDropdown.classList.contains('show')) { |
||
1041 | openDropdown.classList.remove('show'); |
||
1042 | } |
||
1043 | } |
||
1044 | } |
||
1045 | } |
||
1046 | </script> |
||
1047 | </head> |
||
1048 | |||
1049 | <body> |
||
1050 | |||
1051 | <!-- This formating is used to prevent empty textnodes that interfere with the design --> |
||
1052 | <div class="tab" |
||
1053 | ><button class="tablinks" onclick="openTab(event, 'Add')"><?=addslashes(__('Add'))?><i class="fa fa-plus"></i></button |
||
1054 | ><button class="tablinks" id="controlbtn" onclick="openTab(event, 'Control')"><?=addslashes(__('Control'))?><i class="fa fa-arrows"></i></button |
||
1055 | ><button class="tablinks" onclick="openTab(event, 'Extras')"><?=addslashes(__('Extras'))?><i class="fa fa-info-circle"></i></button |
||
1056 | ></div> |
||
1057 | |||
1058 | <div id="workbench"> |
||
1059 | <div id="Add" class="tabcontent"> |
||
1060 | <div class="subtab" |
||
1061 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'File')"><?=addslashes(__('File'))?><i class="fa fa-file"></i></button |
||
1062 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'URL')"><?=addslashes(__('URL'))?><i class="fa fa-globe"></i></button |
||
1063 | ><button class="subtablinks" onclick="openSubtab(event, 'Add', 'Screen')"><?=addslashes(__('Screen'))?><i class="fa fa-video-camera"></i></button |
||
1064 | ></div> |
||
1065 | <div id="File" class="subtabcontent"> |
||
1066 | <div id="file_upload"> |
||
1067 | <form action="upload.php" |
||
1068 | class="dropzone" |
||
1069 | id="palma-dropzone" |
||
1070 | title="<?=addslashes(__('Drag and drop files or click here to upload.'))?>"> |
||
1071 | <div class="dz-default dz-message"> |
||
1072 | <?=__('Add file (click or drop here)')?> |
||
1073 | <i class="fa fa-file fa-2x"></i> |
||
1074 | </div> |
||
1075 | </form> |
||
1076 | <div class="dz-preview dz-file-preview"> |
||
1077 | <div class="dz-details"> |
||
1078 | <div class="dz-filename"><span data-dz-name></span></div> |
||
1079 | <div class="dz-size" data-dz-size></div> |
||
1080 | <img data-dz-thumbnail src="" alt=""> |
||
1081 | </div> |
||
1082 | <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> |
||
1083 | <div class="dz-success-mark"><span> </span></div> |
||
1084 | <div class="dz-error-mark"><span> </span></div> |
||
1085 | <div class="dz-error-message"><span data-dz-errormessage></span></div> |
||
1086 | </div> |
||
1087 | </div> |
||
1088 | </div> |
||
1089 | <div id="URL" class="subtabcontent"> |
||
1090 | <div> |
||
1091 | <input type="text" value="<?=addslashes(__('Add webpage'))?>" |
||
1092 | id="url_field" maxlength="256" size="46" |
||
1093 | onkeydown="if (event.keyCode == 13) document.getElementById('url_button').click()" |
||
1094 | onfocus="clearURLField('<?=addslashes(__('Enter URL'))?>')"> |
||
1095 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1096 | id="url_button" |
||
1097 | onClick="urlToNuc()" title="<?=addslashes(__('Click here to show the webpage on the screen.'))?>"> |
||
1098 | <?=addslashes(__('Enter'))?><i class="fa fa-globe"></i> |
||
1099 | </button> |
||
1100 | </div> |
||
1101 | </div> |
||
1102 | <div id="Screen" class="subtabcontent"> |
||
1103 | <div id="vnc-button" onclick="javascript:getFilePathByOS()"> |
||
1104 | <div id="vnc-button-container"> |
||
1105 | <div id="vnc-button-label"><?=addslashes(__('Add your screen'))?><i class="fa fa-video-camera fa-2x" aria-hidden="true"></i></div> |
||
1106 | <div id="vnc-button-label-subtext"><?=addslashes(__('Download screensharing tool'))?></div> |
||
1107 | </div> |
||
1108 | <a href="<?php echo $winvnc; ?>" download id="download-winvnc" hidden></a> |
||
1109 | <a href="<?php echo $macvnc; ?>" download id="download-macvnc" hidden></a> |
||
1110 | <a href="<?php echo $linuxsh; ?>" download id="download-linux" hidden></a> |
||
1111 | </div> |
||
1112 | <div class="description"> |
||
1113 | <?=addslashes(__('Download your screensharing tool (Windows, Mac and Linux only). Visit the help section for further information.'))?> |
||
1114 | </div> |
||
1115 | </div> |
||
1116 | </div> |
||
1117 | <div id="Control" class="tabcontent"> |
||
1118 | <div class="subtab" |
||
1119 | ><button class="subtablinks" onclick="openSubtab(event, 'Control', 'Layout')"><?=addslashes(__('Layout'))?><i class="fa fa-desktop"></i></button |
||
1120 | ><button class="subtablinks" onclick="openSubtab(event, 'Control', 'Navigate')"><?=addslashes(__('Navigate'))?><i class="fa fa-arrows"></i></button |
||
1121 | ></div> |
||
1122 | <div id="Layout" class="subtabcontent"> |
||
1123 | <div class="screenlayout"> |
||
1124 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1125 | id="g1x1" onclick="miniDisplaySelect(this)" |
||
1126 | title="<?=addslashes(__('Choose screen layout'))?>"> |
||
1127 | <i alt="1" class="fa fa-desktop fa-2x" aria-hidden="true"></i> |
||
1128 | </button> |
||
1129 | </div |
||
1130 | ><div class="screenlayout vertical"> |
||
1131 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1132 | id="g1x2" onclick="miniDisplaySelect(this)" |
||
1133 | title="<?=addslashes(__('Choose screen layout'))?>"> |
||
1134 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1135 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1136 | </button> |
||
1137 | </div |
||
1138 | ><div class="screenlayout"> |
||
1139 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1140 | id="g2x1" onclick="miniDisplaySelect(this)" |
||
1141 | title="<?=addslashes(__('Choose screen layout'))?>"> |
||
1142 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1143 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1144 | </button> |
||
1145 | </div |
||
1146 | ><div class="screenlayout"> |
||
1147 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1148 | id="g1a2" onclick="miniDisplaySelect(this)" |
||
1149 | title="<?=addslashes(__('Choose screen layout'))?>"> |
||
1150 | <div class="layout_left"> |
||
1151 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1152 | </div> |
||
1153 | <div class="layout_right vertical"> |
||
1154 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1155 | <i alt="3" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1156 | </div> |
||
1157 | </button> |
||
1158 | </div |
||
1159 | ><div class="screenlayout"> |
||
1160 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1161 | id="g2x2" onclick="miniDisplaySelect(this)" |
||
1162 | title="<?=addslashes(__('Choose screen layout'))?>"> |
||
1163 | <i alt="1" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1164 | <i alt="2" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1165 | <br /> |
||
1166 | <i alt="3" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1167 | <i alt="4" class="fa fa-desktop fa-1x" aria-hidden="true"></i> |
||
1168 | </button> |
||
1169 | </div> |
||
1170 | </div> |
||
1171 | <div id="Navigate" class="subtabcontent"> |
||
1172 | <div id="windowlist"> |
||
1173 | <!-- filled by updateWindowList and showLayout --> |
||
1174 | </div> |
||
1175 | <button id="closeWindows" class="pure-button pure-button-primary pure-input-rounded" |
||
1176 | onClick="sendToNuc('closeAll=TRUE')" |
||
1177 | title="<?=addslashes(__('Close all windows and remove uploaded files'))?>"> |
||
1178 | <?=addslashes(__('Delete all items'))?> |
||
1179 | </button> |
||
1180 | </div> |
||
1181 | </div> |
||
1182 | <div id="Extras" class="tabcontent"> |
||
1183 | <div class="subtab" |
||
1184 | ><button class="subtablinks active" onclick="openSubtab(event, 'Extras', 'Help')"><?=addslashes(__('Help'))?><i class="fa fa-question-circle"></i></button |
||
1185 | ><button class="subtablinks" onclick="openSubtab(event, 'Extras', 'Feedback')"><?=addslashes(__('Feedback'))?><i class="fa fa-thumbs-o-up"></i></button |
||
1186 | ><button class="subtablinks" onclick="openSubtab(event, 'Extras', 'Users')"><?=addslashes(__('Users'))?><i class="fa fa-users"></i></button |
||
1187 | ></div> |
||
1188 | <div id="Help" class="subtabcontent"> |
||
1189 | <p><?=addslashes(__('With PalMA, you can share documents, websites and your desktop with your learning group.'))?> |
||
1190 | <?=addslashes(__('The PalMA team monitor shows up to four contributions simultaneously.'))?></p> |
||
1191 | <?php |
||
1192 | if (CONFIG_INSTITUTION_URL) { ?> |
||
1193 | <p><?=addslashes(__('For further information about PalMA in this institution'))?> <a href=<?=CONFIG_INSTITUTION_URL?> target="_blank"><?=__('see here.')?></a></p> |
||
1194 | <?php |
||
1195 | } |
||
1196 | ?> |
||
1197 | <h4><?=addslashes(__('Connect'))?><i class="fa fa-wifi"></i></h4> |
||
1198 | <p><?=addslashes(__('Team members can join the session at any time with this URL or QR-Code:'))?></p> |
||
1199 | <p class="url_hint"><?=htmlspecialchars($_SESSION['starturl'])?><br /> |
||
1200 | <?php |
||
1201 | if (!empty($_SESSION['pin'])) { |
||
1202 | echo addslashes(__('PIN: ')); |
||
1203 | echo htmlspecialchars($_SESSION['pin']); |
||
1204 | } |
||
1205 | ?> |
||
1206 | </p> |
||
1207 | <img class="qr-code" src="qrcode/php/qr_img.php?d=<?=htmlspecialchars($_SESSION['starturl'])?>?pin=<?=htmlspecialchars($_SESSION['pin'])?>" alt="QR Code"> |
||
1208 | |||
1209 | <h4><?=addslashes(__('Add'))?><i class="fa fa-plus"></i></h4> |
||
1210 | <p><?=addslashes(__('Use the Add-Section to share content on the PalMA monitor.'))?></p> |
||
1211 | <ul> |
||
1212 | <li><i class="fa fa-file"></i> <?=addslashes(__('For PDF files, office files, images or videos use the file section.'))?></li> |
||
1213 | <li><i class="fa fa-globe"></i> <?=addslashes(__('To display a website use the URL field.'))?></li> |
||
1214 | <li><i class="fa fa-video-camera"></i> <?=addslashes(__('To share your desktop in real time download the VNC screen sharing software and'))?></li> |
||
1215 | <ul> |
||
1216 | <li><i class="fa fa-windows"></i> <?=addslashes(__('Windows:'))?></li> |
||
1217 | <ul> |
||
1218 | <li><?=addslashes(__('Run the downloaded file.'))?></li> |
||
1219 | <li><?=addslashes(__('Double-click the name of your PalMA station in the appearing list.'))?></li> |
||
1220 | </ul> |
||
1221 | <li><i class="fa fa-apple"> </i> <?=addslashes(__('Mac:'))?></li> |
||
1222 | <ul> |
||
1223 | <li><?=addslashes(__('CTRL + click the downloaded file and run it.'))?></li> |
||
1224 | <li><?=addslashes(__('A second window opens, in which you can start "VineServer".'))?></li> |
||
1225 | <li><?=addslashes(__('In the upper left corner, click on "VNC Server".'))?></li> |
||
1226 | <li><?=addslashes(__('Select "Reverse Connection".'))?></li> |
||
1227 | <li><?=addslashes(__('Enter the URL of your PalMA station and click "Connect".'))?></li> |
||
1228 | </ul> |
||
1229 | <li><i class="fa fa-linux"></i> <?=addslashes(__('Linux:'))?></li> |
||
1230 | <ul> |
||
1231 | <li><?=addslashes(__('Run the downloaded shell script.'))?></li> |
||
1232 | <li><?=addslashes(__('Or use this shell command:'))?> <code>x11vnc -connect <?=$_SERVER['HTTP_HOST']?></code></li> |
||
1233 | </ul> |
||
1234 | </ul> |
||
1235 | </ul> |
||
1236 | <h4><?=addslashes(__('Control'))?><i class="fa fa-arrows"></i></h4> |
||
1237 | <p><?=addslashes(__('With the grey monitor buttons at the top you can choose how the shared content should be arranged on the PalMA monitor.'))?></p> |
||
1238 | <p><?=addslashes(__('Below that you find the controls for each item:'))?></p> |
||
1239 | <ul> |
||
1240 | <li><?=addslashes(__('In the top bar you can'))?></li> |
||
1241 | <ul> |
||
1242 | <li><?=addslashes(__('Hide and show'))?><i class="fa fa-eye"></i>,</li> |
||
1243 | <li><?=addslashes(__('Zoom in and out'))?><i class="fa fa-search-plus"></i><i class="fa fa-search-minus"></i>,</li> |
||
1244 | <li><?=addslashes(__('Rotate'))?><i class="fa fa-rotate-left"></i><i class="fa fa-rotate-right"></i>,</li> |
||
1245 | <li><?=addslashes(__('Download'))?><i class="fa fa-download"></i>,</li> |
||
1246 | <li><?=addslashes(__('Delete the item'))?><i class="fa fa-trash-o"></i>.</li> |
||
1247 | </ul> |
||
1248 | <li><?=addslashes(__('Below you find the navigation controls.'))?></li> |
||
1249 | <ul> |
||
1250 | <li><?=addslashes(__('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> |
||
1251 | <li><?=addslashes(__('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> |
||
1252 | </ul> |
||
1253 | </li> |
||
1254 | <li><?=addslashes(__('On the right you can choose the position on the PalMA monitor'))?><i class="fa fa-desktop"></i>.</li> |
||
1255 | </ul> |
||
1256 | <p><?=addslashes(__('Controls that are not available for certain kinds of content are marked grey.'))?></p> |
||
1257 | <h4><?=addslashes(__('Extras'))?><i class="fa fa-info-circle"></i></h4> |
||
1258 | <p><?=addslashes(__('Some additional features are:'))?></p> |
||
1259 | <ul> |
||
1260 | <li><i class="fa fa-question-circle"></i> <?=addslashes(__('This help,'))?></li> |
||
1261 | <li><i class="fa fa-thumbs-o-up"></i> <?=addslashes(__('Your chance to recommend us or give us your thoughts in the "Feedback" section,'))?></li> |
||
1262 | <li><i class="fa fa-users"></i> <?=addslashes(__('A list of all logged-in users as well as a button to disconnect everyone and therefore end the session.'))?></li> |
||
1263 | </ul> |
||
1264 | </div> |
||
1265 | <div id="Feedback" class="subtabcontent"> |
||
1266 | <div id="recommendcontainer"> |
||
1267 | <h3> |
||
1268 | <?=addslashes(__('Recommend us'))?> |
||
1269 | </h3> |
||
1270 | <div> |
||
1271 | <p><?=addslashes(__('If you like PalMA, please recommend us by sharing in your social networks.<br />Enjoy PalMA!'))?></p> |
||
1272 | <!-- Social Media Button Integration, Source: http://sharingbuttons.io/ --> |
||
1273 | <?php $github_url = "https%3A%2F%2Fgithub.com/UB-Mannheim/PalMA/blob/master/README.md"; ?> |
||
1274 | |||
1275 | <!-- Sharingbutton Facebook --> |
||
1276 | <a class="resp-sharing-button__link" href="https://facebook.com/sharer/sharer.php?u=<?=$github_url?>" target="_blank" aria-label=""> |
||
1277 | <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"> |
||
1278 | <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> |
||
1279 | </div> |
||
1280 | </div> |
||
1281 | </a> |
||
1282 | |||
1283 | <!-- Sharingbutton Twitter --> |
||
1284 | <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=""> |
||
1285 | <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"> |
||
1286 | <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> |
||
1287 | </div> |
||
1288 | </div> |
||
1289 | </a> |
||
1290 | |||
1291 | <!-- Sharingbutton Google+ --> |
||
1292 | <a class="resp-sharing-button__link" href="https://plus.google.com/share?url=<?=$github_url?>" target="_blank" aria-label=""> |
||
1293 | <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"> |
||
1294 | <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> |
||
1295 | </div> |
||
1296 | </div> |
||
1297 | </a> |
||
1298 | |||
1299 | <!-- Sharingbutton E-Mail --> |
||
1300 | <a class="resp-sharing-button__link" href="mailto:?subject=Do%20you%20already%20know%20PalMA?%20Take%20a%20Look.&body=<?=$github_url?>" target="_self" aria-label=""> |
||
1301 | <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"> |
||
1302 | <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> |
||
1303 | </div> |
||
1304 | </div> |
||
1305 | </a> |
||
1306 | |||
1307 | <!-- Sharingbutton WhatsApp --> |
||
1308 | <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=""> |
||
1309 | <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"> |
||
1310 | <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> |
||
1311 | </div> |
||
1312 | </div> |
||
1313 | </a> |
||
1314 | |||
1315 | <!-- Sharingbutton Telegram --> |
||
1316 | <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=""> |
||
1317 | <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"> |
||
1318 | <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> |
||
1319 | </div> |
||
1320 | </div> |
||
1321 | </a> |
||
1322 | </div> <!-- Social media buttons and description --> |
||
1323 | </div> <!-- recommendcontainer --> |
||
1324 | <div id="contactcontainer"> |
||
1325 | <h3><?=addslashes(__('Tell us what you think'))?></h3> |
||
1326 | <div> |
||
1327 | <p><?=addslashes(__('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> |
||
1328 | </div> |
||
1329 | </div> <!-- contactcontainer --> |
||
1330 | </div> <!-- feedback --> |
||
1331 | <div id="Users" class="subtabcontent"> |
||
1332 | <div class="dropdown"> |
||
1333 | <button onclick="showDropdown()" class="dropbutton pure-button pure-button-primary"><?=addslashes(__('Select language:'))?> <?=substr($locale, 0, 2)?><i class="fa fa-caret-down"></i></button> |
||
1334 | <div id="languageSelection" class="dropdown-content"> |
||
1335 | <?php |
||
1336 | $dirs = array_slice(scandir('locale'), 2); |
||
1337 | $langs = []; |
||
1338 | for ($n = 0; $n < count($dirs); $n++) { |
||
1339 | if (is_dir("locale/$dirs[$n]")) { |
||
1340 | array_push($langs, substr($dirs[$n], 0, 2)); |
||
1341 | } |
||
1342 | } |
||
1343 | for ($i = 0; $i < count($langs); $i++) { |
||
1344 | echo "<a href=$_SERVER[PHP_SELF]?lang=$langs[$i]>$langs[$i]</a>"; |
||
1345 | } |
||
1346 | ?> |
||
1347 | </div> |
||
1348 | </div> |
||
1349 | <div class="list_container"> |
||
1350 | <table class="userlist" summary="<?=addslashes(__('User list'))?>" title="<?=__('List of connected users')?>"> |
||
1351 | <tbody id="userlist"> |
||
1352 | <tr><td><!-- filled by updateUserList() --></td></tr> |
||
1353 | </tbody> |
||
1354 | </table> |
||
1355 | <div class="description"> |
||
1356 | <?=addslashes(__('New users can join at'))?><br /><?=htmlspecialchars($_SESSION['starturl'])?><br /> |
||
1357 | <?php |
||
1358 | if (!empty($_SESSION['pin'])) { |
||
1359 | echo addslashes(__('PIN: ')); |
||
1360 | echo htmlspecialchars($_SESSION['pin']); |
||
1361 | } |
||
1362 | ?> |
||
1363 | <img class="qr-code" src="qrcode/php/qr_img.php?d=<?=htmlspecialchars($_SESSION['starturl'])?>?pin=<?=htmlspecialchars($_SESSION['pin'])?>" alt="QR Code"> |
||
1364 | </div> |
||
1365 | <button class="pure-button pure-button-primary pure-input-rounded" |
||
1366 | onClick="sendToNuc('logout=ALL')" |
||
1367 | title="<?=addslashes(__('Disconnect all users and end the session'))?>"> |
||
1368 | <?=addslashes(__('End the session'))?> |
||
1369 | </button> |
||
1370 | </div> |
||
1371 | </div> |
||
1372 | </div> |
||
1373 | </div> <!-- workbench --> |
||
1374 | |||
1375 | <div id="footer"> |
||
1376 | <?php |
||
1377 | # Show authorized user name (and address) and allow logout. |
||
1378 | if ($user) { |
||
1379 | echo("<a href=\"logout.php\" title=\"" . |
||
1380 | addslashes(__('Disconnect the current user')) . |
||
1381 | "\">" . addslashes(__('Log out')) . "<i class=\"fa fa-sign-out\"></i></a>"); |
||
1382 | } |
||
1383 | ?> |
||
1384 | </div> <!-- Footer --> |
||
1385 | |||
1386 | </body> |
||
1387 | </html> |
||
1388 |