remote-i3wm-go/static/js/main.js
2023-12-06 17:53:48 +01:00

317 lines
8.6 KiB
JavaScript

let ws
let pointer, scroller, response, screenshotImg
let scrollLastTimestamp, scrollLastValue
let mousePosX, mousePosY, mouseInitPosX, mouseInitPosY
let isLive = false
let isScreenshotWaiting = false
function createWebSocketConnection() {
const protocol = location.protocol === 'https:' ? 'wss' : 'ws'
ws = new WebSocket(`${protocol}://${window.location.hostname}:${window.location.port}/ws`)
ws.onopen = function(event) {
document.querySelector('#disconneced').style.display = 'none'
}
ws.onclose = function(event) {
document.querySelector('#disconneced').style.display = 'block'
window.setTimeout(createWebSocketConnection, 5000)
}
ws.onmessage = function(event) {
let data = JSON.parse(event.data)
if (data.type === 'response') {
response.innerText = data.value
response.style.display = 'block'
window.setTimeout(function() {
response.style.display = 'none'
}, 2500)
} else if (data.type === 'screenshot') {
isScreenshotWaiting = false
screenshotImg.setAttribute('src', 'data:image/png;base64, ' + data.value)
}
}
}
function navigationClickHandler(e) {
if (e.target.getAttribute('href') === '#') {
return
}
Array.from(document.querySelectorAll('.pane')).forEach((item) => {
item.style.display = 'none'
})
document.querySelector(e.target.getAttribute('href')).style.display = 'block'
Array.from(document.querySelectorAll('#nav a')).forEach((item) => {
item.classList.remove('active')
})
e.target.classList.add('active')
}
function buttonClickHandler(e) {
ws.send(e.target.getAttribute('data-msg'))
}
function shortcutClearClickHandler(e) {
document.querySelector('#shortcut-key').value = ''
Array.from(document.querySelectorAll('#shortcuts_special_keys input:checked')).forEach((item) => {
console.log(item.checked)
item.checked = false
console.log(item.checked)
item.change()
})
}
function shortcutSendClickHandler(e) {
let keys = []
let key = document.querySelector('#shortcut-key').value
Array.from(document.querySelectorAll('#shortcuts_special_keys input:checked')).forEach((item) => {
keys.push(item.value)
})
if (keys.length) {
if (key) {
keys.push(key)
}
ws.send('{"type":"keys","value": "' + (keys.join(',').replace('"', '\\"')) + '"}')
}
}
function textClearClickHandler(e) {
document.querySelector('#text').value = ''
}
function textSendClickHandler(e) {
const keys = document.querySelector('#text').value
if (keys.length) {
ws.send('{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}')
}
}
function textKeyUpHandler(e) {
const keys = document.querySelector('#text').value
if (e.keyCode === 13) {
ws.send('{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}')
}
}
function liveTextKeyUpHandler(e) {
const value = e.target.value
if (e.keyCode === 8) {
ws.send('{"type":"key","value": "backspace"}')
} else if (e.keyCode === 13) {
ws.send('{"type":"key","value": "enter"}')
} else if (value.length) {
if (value === ' ') {
ws.send('{"type":"key","value": "space"}')
} else {
ws.send('{"type":"text","value": "' + (value.replace('"', '\\"')) + '"}')
}
e.target.value = ''
}
}
function shortcutsSpecialKeysOnChangeHandler(e) {
Array.from(document.querySelectorAll('#shortcuts_special_keys input:checked')).forEach((item) => {
item.parentNode.classList.add('btn-primary')
item.parentNode.classList.remove('btn-secondary')
})
Array.from(document.querySelectorAll('#shortcuts_special_keys input:not(:checked)')).forEach((item) => {
item.parentNode.classList.add('btn-secondary')
item.parentNode.classList.remove('btn-primary')
})
}
function pointerClickHandler(e) {
ws.send('{"type":"pointer","click":"left"}')
}
function scrollerTouchStartHandler(e) {
mouseInitPosY = e.targetTouches[0].pageY
}
function scrollerTouchMoveHandler(e) {
let touch = e.changedTouches[0]
let value = ((touch.pageY - mouseInitPosY > 0) ? 'down' : 'up')
let now = new Date().getTime()
if (touch.pageY === mouseInitPosY || value === scrollLastValue && scrollLastTimestamp !== null && now - scrollLastTimestamp < 200) {
return
}
scrollLastTimestamp = now
scrollLastValue = value
mouseInitPosY = touch.pageY
ws.send('{"type":"scroll","value": "' + value + '"}')
}
function pointerTouchStartHandler(e) {
const touch = e.targetTouches[0]
mouseInitPosX = touch.pageX
mouseInitPosY = touch.pageY
}
function pointerTouchMoveHandler(e) {
if (e.changedTouches.length === 2) {
return scrollerTouchMoveHandler(e)
}
const touch = e.changedTouches[0]
mousePosX = touch.pageX
mousePosY = touch.pageY
const newX = mousePosX - mouseInitPosX
const newY = mousePosY - mouseInitPosY
mouseInitPosX = mousePosX
mouseInitPosY = mousePosY
let msg = '{"type":"pointer","x": "' + newX + '","y": "' + newY + '"}'
ws.send(msg)
}
function liveHqClickHandler(e) {
return liveClickHandler(e, 'hq')
}
function liveLqClickHandler(e) {
return liveClickHandler(e, 'lq')
}
function liveClickHandler(e, quality) {
if (isLive) {
isLive = false
isScreenshotWaiting = false
document.querySelector('#live-hq').innerText = 'Live HQ'
document.querySelector('#live-lq').innerText = 'Live LQ'
return
}
isLive = true
e.target.innerText = 'Stop live'
let doScreenshot = function() {
if (isLive) {
if (!isScreenshotWaiting) {
isScreenshotWaiting = true
ws.send(`{"type":"screenshot","quality":"${quality}"}`)
}
window.setTimeout(doScreenshot, 100)
}
}
doScreenshot()
}
function fullscreenHandler(e) {
let element = document.querySelector(e.target.getAttribute('data-target'))
let isFullscreen = parseInt(e.target.getAttribute('data-fullscreen'))
document.querySelector('body').classList.toggle('fullscreen', isFullscreen)
if (isFullscreen) {
e.target.setAttribute('data-fullscreen', '0')
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
}
} else {
e.target.setAttribute('data-fullscreen', '1')
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
}
}
}
function documentHashHandler() {
const hash = window.location.hash
if (hash) {
document.querySelector('a[href="' + hash + '"]').click()
} else {
document.querySelector('#nav > li:first-child a').click()
}
}
function addEventListenerOn(selector, eventName, listener) {
if (typeof selector === 'string') {
Array.from(document.querySelectorAll(selector)).forEach((element) => {
element.addEventListener(eventName, listener)
})
} else {
selector.addEventListener(eventName, listener)
}
}
function addListeners() {
addEventListenerOn('#nav a', 'click', navigationClickHandler)
addEventListenerOn('button[data-msg]', 'click', buttonClickHandler)
addEventListenerOn('#shortcut-clear', 'click', shortcutClearClickHandler)
addEventListenerOn('#shortcuts_special_keys input', 'change', shortcutsSpecialKeysOnChangeHandler)
addEventListenerOn('#shortcut-send', 'click', shortcutSendClickHandler)
addEventListenerOn('#text-clear', 'click', textClearClickHandler)
addEventListenerOn('#text-send', 'click', textSendClickHandler)
addEventListenerOn('#text', 'keyup', textKeyUpHandler)
addEventListenerOn('.live-text', 'keyup', liveTextKeyUpHandler)
addEventListenerOn(scroller, 'touchstart', scrollerTouchStartHandler)
addEventListenerOn(scroller, 'touchmove', scrollerTouchMoveHandler)
addEventListenerOn(pointer, 'click', pointerClickHandler)
addEventListenerOn(pointer, 'touchstart', pointerTouchStartHandler)
addEventListenerOn(pointer, 'touchmove', pointerTouchMoveHandler)
addEventListenerOn('#live-hq', 'click', liveHqClickHandler)
addEventListenerOn('#live-lq', 'click', liveLqClickHandler)
addEventListenerOn('.btn-fullscreen', 'click', fullscreenHandler)
}
function bootstrap() {
pointer = document.querySelector('#pointer')
scroller = document.querySelector('#scrollbar')
response = document.querySelector('#response')
screenshotImg = document.querySelector('#screenshot img')
shortcutsSpecialKeysOnChangeHandler()
createWebSocketConnection()
addListeners()
documentHashHandler()
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/static/js/service_worker.js')
}
}
addEventListenerOn(window, 'DOMContentLoaded', bootstrap)