import { MainRc } from "./Main.js"; import { RemoteControlMode } from "../Enums/RemoteControlMode.js"; import { GetDistanceBetween, ConvertUInt8ArrayToBase64 } from "../Utilities.js"; export var AudioButton = document.getElementById("audioButton"); export var MenuButton = document.getElementById("menuButton"); export var MenuFrame = document.getElementById("menuFrame"); export var SessionIDInput = document.getElementById("sessionIDInput"); export var ConnectButton = document.getElementById("connectButton"); export var RequesterNameInput = document.getElementById("nameInput"); export var StatusMessage = document.getElementById("statusMessage"); export var ScreenViewer = document.getElementById("screenViewer"); export var ScreenViewerWrapper = document.getElementById("screenViewerWrapper"); export var Screen2DContext = ScreenViewer.getContext("2d"); export var HorizontalBars = document.querySelectorAll(".horizontal-button-bar"); export var ConnectBox = document.getElementById("connectBox"); export var ScreenSelectBar = document.getElementById("screenSelectBar"); export var QualityBar = document.getElementById("qualityBar"); export var QualitySlider = document.getElementById("qualityRangeInput"); export var AutoQualityAdjustCheckBox = document.getElementById("autoAdjustQualityCheckBox"); export var ActionsBar = document.getElementById("actionsBar"); export var ViewBar = document.getElementById("viewBar"); export var ChangeScreenButton = document.getElementById("changeScreenButton"); export var QualityButton = document.getElementById("qualityButton"); export var FitToScreenButton = document.getElementById("fitToScreenButton"); export var BlockInputButton = document.getElementById("blockInputButton"); export var DisconnectButton = document.getElementById("disconnectButton"); export var FileTransferInput = document.getElementById("fileTransferInput"); export var FileTransferProgress = document.getElementById("fileTransferProgress"); export var KeyboardButton = document.getElementById("keyboardButton"); export var InviteButton = document.getElementById("inviteButton"); export var FileTransferButton = document.getElementById("fileTransferButton"); export var CtrlAltDelButton = document.getElementById("ctrlAltDelButton"); export var TouchKeyboardTextArea = document.getElementById("touchKeyboardTextArea"); export var ClipboardTransferBar = document.getElementById("clipboardTransferBar"); export var ClipboardTransferTextArea = document.getElementById("clipboardTransferTextArea"); export var ClipboardTransferButton = document.getElementById("clipboardTransferButton"); export var ClipboardTransferTypeCheckbox = document.getElementById("clipboardTransferTypeCheckbox"); export var ConnectionP2PIcon = document.getElementById("connectionP2PIcon"); export var ConnectionRelayedIcon = document.getElementById("connectionRelayedIcon"); export var ToastsWrapper = document.getElementById("toastsWrapper"); var lastPointerMove = Date.now(); var isDragging; var currentPointerDevice; var currentTouchCount; var cancelNextViewerClick; var isPinchZooming; var startPinchPoint1; var startPinchPoint2; var lastPinchDistance; var isMenuButtonDragging; var startMenuDraggingY; var startLongPressTimeout; export function ApplyInputHandlers() { AudioButton.addEventListener("click", (ev) => { AudioButton.classList.toggle("toggled"); var toggleOn = AudioButton.classList.contains("toggled"); MainRc.MessageSender.SendToggleAudio(toggleOn); }); ChangeScreenButton.addEventListener("click", (ev) => { closeAllHorizontalBars("screenSelectBar"); ScreenSelectBar.classList.toggle("open"); }); ClipboardTransferButton.addEventListener("click", (ev) => { closeAllHorizontalBars("clipboardTransferBar"); ClipboardTransferBar.classList.toggle("open"); }); ClipboardTransferTextArea.addEventListener("input", (ev) => { if (ClipboardTransferTextArea.value.length == 0) { return; } MainRc.MessageSender.SendClipboardTransfer(ClipboardTransferTextArea.value, ClipboardTransferTypeCheckbox.checked); ClipboardTransferTextArea.blur(); ShowMessage("Clipboard sent!"); }); ConnectButton.addEventListener("click", (ev) => { MainRc.ConnectToClient(); }); CtrlAltDelButton.addEventListener("click", (ev) => { if (!MainRc.ServiceID) { ShowMessage("Not available for this session."); return; } closeAllHorizontalBars(null); MainRc.MessageSender.SendCtrlAltDel(); }); DisconnectButton.addEventListener("click", (ev) => { ConnectButton.removeAttribute("disabled"); MainRc.RCBrowserSockets.Connection.stop(); if (location.search.includes("fromApi=true")) { window.close(); } }); document.querySelectorAll("#sessionIDInput, #nameInput").forEach(x => { x.addEventListener("keypress", (ev) => { if (ev.key.toLowerCase() == "enter") { MainRc.ConnectToClient(); } }); }); FileTransferButton.addEventListener("click", (ev) => { FileTransferInput.click(); }); FileTransferInput.addEventListener("change", (ev) => { uploadFiles(FileTransferInput.files); }); FitToScreenButton.addEventListener("click", (ev) => { FitToScreenButton.classList.toggle("toggled"); if (FitToScreenButton.classList.contains("toggled")) { ScreenViewer.style.removeProperty("max-width"); ScreenViewer.style.removeProperty("max-height"); } else { ScreenViewer.style.maxWidth = "unset"; ScreenViewer.style.maxHeight = "unset"; } }); BlockInputButton.addEventListener("click", (ev) => { var button = ev.currentTarget; button.classList.toggle("toggled"); if (button.classList.contains("toggled")) { MainRc.MessageSender.SendToggleBlockInput(true); } else { MainRc.MessageSender.SendToggleBlockInput(false); } }); InviteButton.addEventListener("click", (ev) => { var url = ""; if (MainRc.Mode == RemoteControlMode.Normal) { url = `${location.origin}${location.pathname}?sessionID=${MainRc.ClientID}`; } else { url = `${location.origin}${location.pathname}?clientID=${MainRc.ClientID}&serviceID=${MainRc.ServiceID}`; } MainRc.ClipboardWatcher.SetClipboardText(url); ShowMessage("Link copied to clipboard."); }); KeyboardButton.addEventListener("click", (ev) => { closeAllHorizontalBars(null); TouchKeyboardTextArea.focus(); TouchKeyboardTextArea.setSelectionRange(TouchKeyboardTextArea.value.length, TouchKeyboardTextArea.value.length); MenuFrame.classList.remove("open"); MenuButton.classList.remove("open"); }); MenuButton.addEventListener("click", (ev) => { if (isMenuButtonDragging) { isMenuButtonDragging = false; return; } MenuFrame.classList.toggle("open"); MenuButton.classList.toggle("open"); closeAllHorizontalBars(null); }); MenuButton.addEventListener("mousedown", (ev) => { isMenuButtonDragging = false; startMenuDraggingY = ev.clientY; window.addEventListener("mousemove", moveMenuButton); window.addEventListener("mouseup", removeMouseButtonWindowListeners); window.addEventListener("mouseleave", removeMouseButtonWindowListeners); }); MenuButton.addEventListener("touchmove", (ev) => { ev.preventDefault(); ev.stopPropagation(); MenuButton.style.top = `${ev.touches[0].clientY}px`; }); QualityButton.addEventListener("click", (ev) => { closeAllHorizontalBars("qualityBar"); QualityBar.classList.toggle("open"); }); QualitySlider.addEventListener("change", (ev) => { MainRc.MessageSender.SendQualityChange(Number(QualitySlider.value)); }); AutoQualityAdjustCheckBox.addEventListener("change", ev => { MainRc.MessageSender.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked); }); ScreenViewer.addEventListener("pointermove", function (e) { currentPointerDevice = e.pointerType; }); ScreenViewer.addEventListener("pointerdown", function (e) { currentPointerDevice = e.pointerType; }); ScreenViewer.addEventListener("pointerenter", function (e) { currentPointerDevice = e.pointerType; }); ScreenViewer.addEventListener("mousemove", function (e) { e.preventDefault(); if (Date.now() - lastPointerMove < 25) { return; } lastPointerMove = Date.now(); var percentX = e.offsetX / ScreenViewer.clientWidth; var percentY = e.offsetY / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseMove(percentX, percentY); }); ScreenViewer.addEventListener("mousedown", function (e) { if (currentPointerDevice == "touch") { return; } if (e.button != 0 && e.button != 2) { return; } e.preventDefault(); var percentX = e.offsetX / ScreenViewer.clientWidth; var percentY = e.offsetY / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseDown(e.button, percentX, percentY); }); ScreenViewer.addEventListener("mouseup", function (e) { if (currentPointerDevice == "touch") { return; } if (e.button != 0 && e.button != 2) { return; } e.preventDefault(); var percentX = e.offsetX / ScreenViewer.clientWidth; var percentY = e.offsetY / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseUp(e.button, percentX, percentY); }); ScreenViewer.addEventListener("click", function (e) { if (cancelNextViewerClick) { cancelNextViewerClick = false; return; } if (currentPointerDevice == "mouse") { e.preventDefault(); e.stopPropagation(); } else if (currentPointerDevice == "touch" && currentTouchCount == 0) { var percentX = e.offsetX / ScreenViewer.clientWidth; var percentY = e.offsetY / ScreenViewer.clientHeight; MainRc.MessageSender.SendTap(percentX, percentY); } }); ScreenViewer.addEventListener("touchstart", function (e) { currentTouchCount = e.touches.length; if (currentTouchCount == 1) { startLongPressTimeout = window.setTimeout(() => { var percentX = e.touches[0].pageX / ScreenViewer.clientWidth; var percentY = e.touches[0].pageY / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseDown(2, percentX, percentY); MainRc.MessageSender.SendMouseUp(2, percentX, percentY); }, 1000); } if (currentTouchCount > 1) { cancelNextViewerClick = true; } if (currentTouchCount == 2) { startPinchPoint1 = { X: e.touches[0].pageX, Y: e.touches[0].pageY, IsEmpty: false }; startPinchPoint2 = { X: e.touches[1].pageX, Y: e.touches[1].pageY, IsEmpty: false }; lastPinchDistance = GetDistanceBetween(startPinchPoint1.X, startPinchPoint1.Y, startPinchPoint2.X, startPinchPoint2.Y); } isDragging = false; KeyboardButton.removeAttribute("hidden"); var focusedInput = document.querySelector("input:focus"); if (focusedInput) { focusedInput.blur(); } }); ScreenViewer.addEventListener("touchmove", function (e) { currentTouchCount = e.touches.length; clearTimeout(startLongPressTimeout); var percentX = (e.touches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth; var percentY = (e.touches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight; if (e.touches.length == 2) { var pinchPoint1 = { X: e.touches[0].pageX, Y: e.touches[0].pageY, IsEmpty: false }; var pinchPoint2 = { X: e.touches[1].pageX, Y: e.touches[1].pageY, IsEmpty: false }; var pinchDistance = GetDistanceBetween(pinchPoint1.X, pinchPoint1.Y, pinchPoint2.X, pinchPoint2.Y); if (Math.abs(pinchDistance - lastPinchDistance) > 5) { isPinchZooming = true; if (FitToScreenButton.classList.contains("toggled")) { FitToScreenButton.click(); } var currentWidth = ScreenViewer.clientWidth; var currentHeight = ScreenViewer.clientHeight; var currentWidthPercent = Number(ScreenViewer.style.width.slice(0, -1)); var newWidthPercent = Math.max(100, currentWidthPercent + (pinchDistance - lastPinchDistance)); ScreenViewer.style.width = String(newWidthPercent) + "%"; var heightChange = ScreenViewer.clientHeight - currentHeight; var widthChange = ScreenViewer.clientWidth - currentWidth; var scrollPercentX = ScreenViewerWrapper.scrollLeft / (ScreenViewerWrapper.scrollWidth - ScreenViewerWrapper.clientWidth); var scrollPercentY = ScreenViewerWrapper.scrollTop / (ScreenViewerWrapper.scrollHeight - ScreenViewerWrapper.clientHeight); ScreenViewerWrapper.scrollBy(widthChange * scrollPercentX, heightChange * scrollPercentY); lastPinchDistance = pinchDistance; } return; } else if (isDragging) { e.preventDefault(); e.stopPropagation(); MainRc.MessageSender.SendMouseMove(percentX, percentY); } }); ScreenViewer.addEventListener("touchend", function (e) { currentTouchCount = e.touches.length; clearTimeout(startLongPressTimeout); if (e.touches.length == 1 && !isPinchZooming) { isDragging = true; var percentX = (e.touches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth; var percentY = (e.touches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseMove(percentX, percentY); MainRc.MessageSender.SendMouseDown(0, percentX, percentY); return; } if (currentTouchCount == 0) { cancelNextViewerClick = false; isPinchZooming = false; startPinchPoint1 = null; startPinchPoint2 = null; } if (isDragging) { var percentX = (e.changedTouches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth; var percentY = (e.changedTouches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight; MainRc.MessageSender.SendMouseUp(0, percentX, percentY); } isDragging = false; }); ScreenViewer.addEventListener("contextmenu", (ev) => { ev.preventDefault(); }); ScreenViewer.addEventListener("wheel", function (e) { e.preventDefault(); MainRc.MessageSender.SendMouseWheel(e.deltaX, e.deltaY); }); TouchKeyboardTextArea.addEventListener("input", (ev) => { if (TouchKeyboardTextArea.value.length == 1) { MainRc.MessageSender.SendKeyPress("Backspace"); } else if (TouchKeyboardTextArea.value.endsWith("\n")) { MainRc.MessageSender.SendKeyPress("Enter"); } else if (TouchKeyboardTextArea.value.endsWith(" ")) { MainRc.MessageSender.SendKeyPress(" "); } else { var input = TouchKeyboardTextArea.value.trim().substr(1); for (var i = 0; i < input.length; i++) { var character = input.charAt(i); var sendShift = character.match(/[A-Z~!@#$%^&*()_+{}|<>?]/); if (sendShift) { MainRc.MessageSender.SendKeyDown("Shift"); } MainRc.MessageSender.SendKeyPress(character); if (sendShift) { MainRc.MessageSender.SendKeyUp("Shift"); } } } window.setTimeout(() => { TouchKeyboardTextArea.value = " #"; TouchKeyboardTextArea.setSelectionRange(TouchKeyboardTextArea.value.length, TouchKeyboardTextArea.value.length); }); }); window.addEventListener("keydown", function (e) { if (document.querySelector("input:focus") || document.querySelector("textarea:focus")) { return; } e.preventDefault(); MainRc.MessageSender.SendKeyDown(e.key); }); window.addEventListener("keyup", function (e) { if (document.querySelector("input:focus") || document.querySelector("textarea:focus")) { return; } e.preventDefault(); MainRc.MessageSender.SendKeyUp(e.key); }); window.ondragover = function (e) { e.preventDefault(); e.dataTransfer.dropEffect = "copy"; }; window.ondrop = function (e) { e.preventDefault(); if (e.dataTransfer.files.length < 1) { return; } uploadFiles(e.dataTransfer.files); }; } export function Prompt(promptMessage) { return new Promise((resolve, reject) => { var modalDiv = document.createElement("div"); modalDiv.classList.add("modal-prompt"); var messageDiv = document.createElement("div"); messageDiv.innerHTML = promptMessage; var responseInput = document.createElement("input"); var buttonsDiv = document.createElement("div"); buttonsDiv.classList.add("buttons-footer"); var cancelButton = document.createElement("button"); cancelButton.innerHTML = "Cancel"; var okButton = document.createElement("button"); okButton.innerHTML = "OK"; buttonsDiv.appendChild(okButton); buttonsDiv.appendChild(cancelButton); modalDiv.appendChild(messageDiv); modalDiv.appendChild(responseInput); modalDiv.appendChild(buttonsDiv); document.body.appendChild(modalDiv); okButton.onclick = () => { modalDiv.remove(); resolve(responseInput.value); }; cancelButton.onclick = () => { modalDiv.remove(); resolve(null); }; }); } export function SetScreenSize(width, height) { ScreenViewer.width = width; ScreenViewer.height = height; Screen2DContext.clearRect(0, 0, width, height); } export function ShowMessage(message) { var messageDiv = document.createElement("div"); messageDiv.classList.add("toast-message"); messageDiv.innerHTML = message; ToastsWrapper.appendChild(messageDiv); window.setTimeout(() => { messageDiv.remove(); }, 5000); } export function UpdateCursor(cursor) { if (cursor.CssOverride) { ScreenViewer.style.cursor = cursor.CssOverride; } else if (cursor.ImageBytes.byteLength == 0) { ScreenViewer.style.cursor = "default"; } else { var base64 = ConvertUInt8ArrayToBase64(cursor.ImageBytes); ScreenViewer.style.cursor = `url('data:image/png;base64,${base64}') ${cursor.HotSpot.X} ${cursor.HotSpot.Y}, default`; } } export function UpdateDisplays(selectedDisplay, displayNames) { ScreenSelectBar.innerHTML = ""; for (let i = 0; i < displayNames.length; i++) { var button = document.createElement("button"); button.innerHTML = `Monitor ${i}`; button.classList.add("horizontal-bar-button"); if (displayNames[i] == selectedDisplay) { button.classList.add("toggled"); } ScreenSelectBar.appendChild(button); button.onclick = (ev) => { this.SendSelectScreen(displayNames[i]); document.querySelectorAll("#screenSelectBar .horizontal-bar-button").forEach(button => { button.classList.remove("toggled"); }); ev.currentTarget.classList.add("toggled"); }; } } function uploadFiles(fileList) { ShowMessage("File upload started..."); FileTransferProgress.value = 0; FileTransferProgress.parentElement.removeAttribute("hidden"); var strPath = "/API/FileSharing/"; var fd = new FormData(); for (var i = 0; i < fileList.length; i++) { fd.append('fileUpload' + i, fileList[i]); } var xhr = new XMLHttpRequest(); xhr.open('POST', strPath, true); xhr.addEventListener("load", function () { FileTransferProgress.parentElement.setAttribute("hidden", "hidden"); if (xhr.status === 200) { ShowMessage("File upload completed."); MainRc.RCBrowserSockets.SendSharedFileIDs(xhr.responseText); } else { ShowMessage("File upload failed."); } }); xhr.addEventListener("error", () => { FileTransferProgress.parentElement.setAttribute("hidden", "hidden"); ShowMessage("File upload failed."); }); xhr.addEventListener("progress", function (e) { FileTransferProgress.value = isFinite(e.loaded / e.total) ? e.loaded / e.total : 0; }); xhr.send(fd); } function closeAllHorizontalBars(exceptBarId) { HorizontalBars.forEach(x => { if (x.id != exceptBarId) { x.classList.remove('open'); } }); } function moveMenuButton(ev) { if (Math.abs(ev.clientY - startMenuDraggingY) > 5) { if (ev.clientY < 0 || ev.clientY > window.innerHeight) { return; } isMenuButtonDragging = true; MenuButton.style.top = `${ev.clientY}px`; } } function removeMouseButtonWindowListeners(ev) { window.removeEventListener("mousemove", moveMenuButton); window.removeEventListener("mouseup", removeMouseButtonWindowListeners); window.removeEventListener("mouseleave", removeMouseButtonWindowListeners); } //# sourceMappingURL=UI.js.map