mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Added login screen (simulated for now) and improved styling
This commit is contained in:
@@ -20,6 +20,70 @@
|
|||||||
body {
|
body {
|
||||||
background: black;
|
background: black;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-ui {
|
||||||
|
background: #342;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-logo {
|
||||||
|
position: relative;
|
||||||
|
bottom: 0;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-dialog-middle {
|
||||||
|
width: 100%;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-dialog {
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
padding: 1em;
|
||||||
|
border: 0.2em solid black;
|
||||||
|
|
||||||
|
-khtml-border-radius: 0.5em;
|
||||||
|
-webkit-border-radius: 0.5em;
|
||||||
|
-moz-border-radius: 0.5em;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
|
||||||
|
max-width: 75%;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-dialog h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0em;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid silver;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-dialog #buttons {
|
||||||
|
border-top: 1px solid silver;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#login-dialog #login-fields {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.errorDialogOuter {
|
div.errorDialogOuter {
|
||||||
|
BIN
guacamole/web-client/web/images/login-logo.png
Normal file
BIN
guacamole/web-client/web/images/login-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@@ -30,44 +30,79 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- Menu -->
|
<div id="login-ui">
|
||||||
<div id="menu">
|
<div id="login-dialog-middle">
|
||||||
|
|
||||||
<!-- Clipboard -->
|
<div id="login-logo">
|
||||||
<button id="showClipboard">Show Clipboard</button>
|
<img src="images/login-logo.png" alt="\_GUAC_/"/>
|
||||||
<div id="clipboardDiv">
|
</div>
|
||||||
<h2>Clipboard</h2>
|
|
||||||
<p>
|
<div id="login-dialog">
|
||||||
Text copied/cut within VNC will appear here. Changes to the text will affect the VNC clipboard, and will be pastable within VNC. Use the textbox below as an interface between the client and server clipboards.
|
|
||||||
</p>
|
<h1>Guacamole Login</h1>
|
||||||
<textarea rows="10" cols="40" id="clipboard"></textarea>
|
<form id="login-form" action="#">
|
||||||
|
<table id="login-fields">
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<td><input type="text" name="username" id="username"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Password</th>
|
||||||
|
<td><input type="password" name="password" id="password"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div id="buttons">
|
||||||
|
<input type="submit" name="login" id="login" value="Login"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main UI - hidden until login succeeds -->
|
||||||
|
<div id="main-guacamole-ui" style="display: none">
|
||||||
|
|
||||||
|
<!-- Menu -->
|
||||||
|
<div id="menu">
|
||||||
|
|
||||||
|
<!-- Clipboard -->
|
||||||
|
<button id="showClipboard">Show Clipboard</button>
|
||||||
|
<div id="clipboardDiv">
|
||||||
|
<h2>Clipboard</h2>
|
||||||
|
<p>
|
||||||
|
Text copied/cut within Guacamole will appear here. Changes to the text will affect the remote clipboard, and will be pastable within the remote desktop. Use the textbox below as an interface between the client and server clipboards.
|
||||||
|
</p>
|
||||||
|
<textarea rows="10" cols="40" id="clipboard"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="showKeyboard">Show Keyboard</button>
|
||||||
|
<button id="CtrlAltDelete">Ctrl-Alt-Delete</button>
|
||||||
|
|
||||||
|
<!-- Logo and status -->
|
||||||
|
<img id="logo" src="images/guacamole-logo.png" alt="Guacamole" title="__GUAC_VERSION"/>
|
||||||
|
<span id="state"></span>
|
||||||
|
|
||||||
|
<a href="agpl-3.0-standalone.html"><img id="license" src="images/agpl-logo.png" alt="AGPLv3"/></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="showKeyboard">Show Keyboard</button>
|
|
||||||
<button id="CtrlAltDelete">Ctrl-Alt-Delete</button>
|
|
||||||
|
|
||||||
<!-- Logo and status -->
|
<!-- Display -->
|
||||||
<img id="logo" src="images/guacamole-logo.png" alt="Guacamole" title="__GUAC_VERSION"/>
|
<div id="display" class="guac-display guac-loading">
|
||||||
<span id="state"></span>
|
<!-- On-screen keyboard -->
|
||||||
|
<div id="keyboardContainer"></div>
|
||||||
<a href="agpl-3.0-standalone.html"><img id="license" src="images/agpl-logo.png" alt="AGPLv3"/></a>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Display -->
|
<!-- Error Dialog-->
|
||||||
<div id="display" class="guac-display guac-loading">
|
<div id="errorDialog" class="errorDialogOuter">
|
||||||
<!-- On-screen keyboard -->
|
<div class="errorDialogMiddle">
|
||||||
<div id="keyboardContainer"></div>
|
<div class="errorDialog">
|
||||||
</div>
|
<h1>Error</h1>
|
||||||
|
<p id="errorText"></p>
|
||||||
|
<div class="buttons"><button id="reconnect">Reconnect</button></div>
|
||||||
<!-- Error Dialog-->
|
</div>
|
||||||
<div id="errorDialog" class="errorDialogOuter">
|
|
||||||
<div class="errorDialogMiddle">
|
|
||||||
<div class="errorDialog">
|
|
||||||
<h1>Error</h1>
|
|
||||||
<p id="errorText"></p>
|
|
||||||
<div class="buttons"><button id="reconnect">Reconnect</button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,166 +119,187 @@
|
|||||||
<!-- Init -->
|
<!-- Init -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
var menu = document.getElementById("menu");
|
var loginForm = document.getElementById("login-form");
|
||||||
var display = document.getElementById("display");
|
var loginUI = document.getElementById("login-ui");
|
||||||
var logo = document.getElementById("logo");
|
|
||||||
|
|
||||||
var errorDialog = document.getElementById("errorDialog");
|
loginForm.onsubmit = function() {
|
||||||
var errorDialogText = document.getElementById("errorText");
|
|
||||||
|
|
||||||
// Position display correctly
|
// FIXME: Do ACTUAL login here
|
||||||
window.onresize = function() {
|
|
||||||
display.style.top = menu.offsetHeight + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onresize();
|
loginUI.style.display = "none";
|
||||||
|
startGuacamole();
|
||||||
|
|
||||||
// Instantiate client
|
return false;
|
||||||
var guac = new GuacamoleClient(display);
|
|
||||||
|
|
||||||
var state = document.getElementById("state");
|
|
||||||
guac.setOnStateChangeHandler(function(clientState) {
|
|
||||||
|
|
||||||
switch (clientState) {
|
|
||||||
case 0:
|
|
||||||
state.textContent = "Idle."
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
state.textContent = "Connecting...";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
state.textContent = "Connected, waiting for first update...";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
display.className = display.className.replace(/guac-loading/, '');
|
|
||||||
menu.className = "connected";
|
|
||||||
state.textContent = "Connected.";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
state.textContent = "Disconnecting...";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
state.textContent = "Disconnected.";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
state.textContent = "Unknown";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Cache error image (might not be available when error occurs)
|
|
||||||
var guacErrorImage = new Image();
|
|
||||||
guacErrorImage.src = "images/noguacamole-logo.png";
|
|
||||||
|
|
||||||
guac.setErrorHandler(function(error) {
|
|
||||||
menu.className = "error";
|
|
||||||
logo.src = guacErrorImage.src;
|
|
||||||
errorDialogText.textContent = error;
|
|
||||||
errorDialog.style.visibility = "visible";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Reconnect button
|
|
||||||
var reconnect = document.getElementById("reconnect");
|
|
||||||
reconnect.onclick = function() {
|
|
||||||
window.location.reload();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Connect
|
|
||||||
guac.connect();
|
|
||||||
|
|
||||||
// Disconnect on close
|
|
||||||
window.onunload = function() {
|
|
||||||
guac.disconnect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle clipboard events
|
// Shows guacamole interface and initiates connection to guacamole
|
||||||
var clipboardElement = document.getElementById("clipboard");
|
function startGuacamole() {
|
||||||
clipboardElement.onchange = function() {
|
|
||||||
|
|
||||||
var text = clipboardElement.value;
|
document.getElementById("main-guacamole-ui").style.display = "block";
|
||||||
guac.setClipboard(text);
|
|
||||||
|
|
||||||
};
|
var menu = document.getElementById("menu");
|
||||||
|
var display = document.getElementById("display");
|
||||||
|
var logo = document.getElementById("logo");
|
||||||
|
|
||||||
// Ignore keypresses when clipboard is focused
|
var errorDialog = document.getElementById("errorDialog");
|
||||||
clipboardElement.onfocus = function() {
|
var errorDialogText = document.getElementById("errorText");
|
||||||
guac.disableKeyboard();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Capture keypresses when clipboard is not focused
|
// Position display correctly
|
||||||
clipboardElement.onblur = function() {
|
window.onresize = function() {
|
||||||
guac.enableKeyboard();
|
display.style.top = menu.offsetHeight + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
// Server copy handler
|
window.onresize();
|
||||||
guac.setClipboardHandler(
|
|
||||||
function(data) {
|
|
||||||
clipboardElement.value = data;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Instantiate client
|
||||||
|
var guac = new GuacamoleClient(display);
|
||||||
|
|
||||||
// Show/Hide clipboard
|
var state = document.getElementById("state");
|
||||||
var clipboardDiv = document.getElementById("clipboardDiv");
|
guac.setOnStateChangeHandler(function(clientState) {
|
||||||
var showClipboard = document.getElementById("showClipboard");
|
|
||||||
showClipboard.onclick = function() {
|
|
||||||
|
|
||||||
var displayed = clipboardDiv.style.display;
|
switch (clientState) {
|
||||||
if (displayed != "block") {
|
case 0:
|
||||||
clipboardDiv.style.display = "block";
|
state.textContent = "Idle."
|
||||||
showClipboard.innerHTML = "Hide Clipboard";
|
break;
|
||||||
}
|
case 1:
|
||||||
else {
|
state.textContent = "Connecting...";
|
||||||
clipboardDiv.style.display = "none";
|
break;
|
||||||
showClipboard.innerHTML = "Show Clipboard";
|
case 2:
|
||||||
clipboardElement.onchange();
|
state.textContent = "Connected, waiting for first update...";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
display.className = display.className.replace(/guac-loading/, '');
|
||||||
|
menu.className = "connected";
|
||||||
|
state.textContent = "Connected.";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
state.textContent = "Disconnecting...";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
state.textContent = "Disconnected.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state.textContent = "Unknown";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cache error image (might not be available when error occurs)
|
||||||
|
var guacErrorImage = new Image();
|
||||||
|
guacErrorImage.src = "images/noguacamole-logo.png";
|
||||||
|
|
||||||
|
guac.setErrorHandler(function(error) {
|
||||||
|
menu.className = "error";
|
||||||
|
logo.src = guacErrorImage.src;
|
||||||
|
errorDialogText.textContent = error;
|
||||||
|
errorDialog.style.visibility = "visible";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reconnect button
|
||||||
|
var reconnect = document.getElementById("reconnect");
|
||||||
|
reconnect.onclick = function() {
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Connect
|
||||||
|
guac.connect();
|
||||||
|
|
||||||
|
// Disconnect on close
|
||||||
|
window.onunload = function() {
|
||||||
|
guac.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
// Handle clipboard events
|
||||||
|
var clipboardElement = document.getElementById("clipboard");
|
||||||
|
clipboardElement.onchange = function() {
|
||||||
|
|
||||||
|
var text = clipboardElement.value;
|
||||||
|
guac.setClipboard(text);
|
||||||
|
|
||||||
// Show/Hide keyboard
|
};
|
||||||
var keyboardContainer = document.getElementById("keyboardContainer");
|
|
||||||
var showKeyboard = document.getElementById("showKeyboard");
|
|
||||||
showKeyboard.onclick = function() {
|
|
||||||
|
|
||||||
var displayed = keyboardContainer.style.display;
|
// Ignore keypresses when clipboard is focused
|
||||||
if (displayed != "block") {
|
clipboardElement.onfocus = function() {
|
||||||
keyboardContainer.style.display = "block";
|
guac.disableKeyboard();
|
||||||
showKeyboard.textContent = "Hide Keyboard";
|
};
|
||||||
}
|
|
||||||
else {
|
|
||||||
keyboardContainer.style.display = "none";
|
|
||||||
showKeyboard.textContent = "Show Keyboard";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
// Capture keypresses when clipboard is not focused
|
||||||
|
clipboardElement.onblur = function() {
|
||||||
|
guac.enableKeyboard();
|
||||||
|
};
|
||||||
|
|
||||||
// On-screen keyboard
|
// Server copy handler
|
||||||
var osKeyboard = new GuacamoleOnScreenKeyboard("layouts/en-us-qwerty.xml");
|
guac.setClipboardHandler(
|
||||||
keyboardContainer.appendChild(osKeyboard);
|
function(data) {
|
||||||
|
clipboardElement.value = data;
|
||||||
osKeyboard.setKeyPressedHandler(
|
|
||||||
function(keysym) {
|
|
||||||
guac.pressKey(keysym);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
osKeyboard.setKeyReleasedHandler(
|
|
||||||
function(keysym) {
|
// Show/Hide clipboard
|
||||||
guac.releaseKey(keysym);
|
var clipboardDiv = document.getElementById("clipboardDiv");
|
||||||
|
var showClipboard = document.getElementById("showClipboard");
|
||||||
|
showClipboard.onclick = function() {
|
||||||
|
|
||||||
|
var displayed = clipboardDiv.style.display;
|
||||||
|
if (displayed != "block") {
|
||||||
|
clipboardDiv.style.display = "block";
|
||||||
|
showClipboard.innerHTML = "Hide Clipboard";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clipboardDiv.style.display = "none";
|
||||||
|
showClipboard.innerHTML = "Show Clipboard";
|
||||||
|
clipboardElement.onchange();
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
// Send Ctrl-Alt-Delete
|
};
|
||||||
var CtrlAltDelete = document.getElementById("CtrlAltDelete");
|
|
||||||
|
|
||||||
|
// Show/Hide keyboard
|
||||||
|
var keyboardContainer = document.getElementById("keyboardContainer");
|
||||||
|
var showKeyboard = document.getElementById("showKeyboard");
|
||||||
|
showKeyboard.onclick = function() {
|
||||||
|
|
||||||
|
var displayed = keyboardContainer.style.display;
|
||||||
|
if (displayed != "block") {
|
||||||
|
keyboardContainer.style.display = "block";
|
||||||
|
showKeyboard.textContent = "Hide Keyboard";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
keyboardContainer.style.display = "none";
|
||||||
|
showKeyboard.textContent = "Show Keyboard";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// On-screen keyboard
|
||||||
|
var osKeyboard = new GuacamoleOnScreenKeyboard("layouts/en-us-qwerty.xml");
|
||||||
|
keyboardContainer.appendChild(osKeyboard);
|
||||||
|
|
||||||
|
osKeyboard.setKeyPressedHandler(
|
||||||
|
function(keysym) {
|
||||||
|
guac.pressKey(keysym);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
osKeyboard.setKeyReleasedHandler(
|
||||||
|
function(keysym) {
|
||||||
|
guac.releaseKey(keysym);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send Ctrl-Alt-Delete
|
||||||
|
var CtrlAltDelete = document.getElementById("CtrlAltDelete");
|
||||||
|
|
||||||
|
CtrlAltDelete.onclick = function() {
|
||||||
|
guac.pressKey(KEYSYM_CTRL);
|
||||||
|
guac.pressKey(KEYSYM_ALT);
|
||||||
|
guac.pressKey(KEYSYM_DELETE);
|
||||||
|
guac.releaseKey(KEYSYM_DELETE);
|
||||||
|
guac.releaseKey(KEYSYM_ALT);
|
||||||
|
guac.releaseKey(KEYSYM_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
CtrlAltDelete.onclick = function() {
|
|
||||||
guac.pressKey(KEYSYM_CTRL);
|
|
||||||
guac.pressKey(KEYSYM_ALT);
|
|
||||||
guac.pressKey(KEYSYM_DELETE);
|
|
||||||
guac.releaseKey(KEYSYM_DELETE);
|
|
||||||
guac.releaseKey(KEYSYM_ALT);
|
|
||||||
guac.releaseKey(KEYSYM_CTRL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
Reference in New Issue
Block a user