Слияние кода завершено, страница обновится автоматически
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>STF-EASE</title>
<style>
html, body {
margin: 0;
padding: 0;
}
body {
text-align: center;
background: rgba(100, 100, 100, .5);
}
.container canvas {
margin: 8px;
}
a:hover {
color:blue;
}
</style>
</head>
<body lang="zh-CN">
<div class="container"></div>
<select id="quality" style="position: absolute; right: 12px; top: 12px; font-size: 16px; width: 80px; height: 28px;">
<option value="720">高清</option>
<option value="360" selected>中等</option>
<option value="240">略差</option>
<option value="120">抽象</option>
</select>
<label style="position: absolute; right: 14px; top: 42px; font-size: 16px; width: 80px; text-align: right; display: none;">
<input id="muti" type="checkbox"/> 群控
</label>
<button id="btn-install" style="position: absolute; right: 100px; top: 12px; font-size: 16px; width: 100px; height: 28px; padding: 0; line-height: 28px;">
安装应用
</button>
<select id="packages" style="position: absolute; right: 210px; top: 12px; font-size: 16px; height: 28px;">
<option value="">打开应用</option>
</select>
<div id="loading" style="position: fixed; top: 0; right: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, .5); display: none; font-size: 72px; text-align: center; padding-top: 100px;">
请稍等
</div>
<script type="module">
const btnInstall = document.querySelector('#btn-install')
const selectPackages = document.querySelector('#packages')
const loading = document.querySelector('#loading')
const ids = location.pathname.match(/[^\/,]+/g)
const default_options = selectPackages.innerHTML
const fetch_pkgs = () => {
let id = ids[0]
fetch(`/action/list_packages?id=${id}`, { cache: 'no-cache' }).then(res => res.json())
.then(function (pkgs) {
selectPackages.innerHTML = default_options + pkgs.filter(p => !p.includes('android')).sort().map(p => `<option value="${p}">${p}</option>`)
selectPackages.addEventListener('change', function () {
loading.style.display = 'block'
fetch(`/action/open_app?id=${id}&pkg=${selectPackages.value}`, { cache: 'no-cache' }).then(function () {
loading.style.display = 'none'
})
})
})
}
if (ids.length > 1) {
btnInstall.style.display = 'none'
selectPackages.style.display = 'none'
} else {
let id = ids[0];
fetch_pkgs()
btnInstall.addEventListener('click', function () {
const url = prompt('输入apk下载地址:')
if (url) {
loading.style.display = 'block'
fetch(`/action/install_from_url`, {
method: 'POST',
headers: {
'Content-Type': "application/json"
},
body: JSON.stringify({
id, url,
})
}).then(function () {
loading.style.display = 'none'
fetch_pkgs()
})
}
})
}
</script>
<script type="module" >
import Ease, { defaultCommands, ActionType } from "./src/index.ts";
const query = (items => items.reduce((m, a) => {
const [k, v] = a.split('=')
m[k]= v
return m
}, {}))((location.search || '?').slice(1).split('&'))
const urls = query.url ? ['ws://' + query.url] : location.pathname.match(/[^\/,]+/g).map(id => 'ws://' + location.host + '/' + id)
const container = document.querySelector('.container')
const quality = document.querySelector('#quality')
const muti = document.querySelector('#muti')
if (urls.length > 1) {
muti.parentElement.style.display = 'block'
}
let ws_list = []
const sender = function (...args) {
ws_list.forEach(w => {
w.send.apply(w, args)
})
}
const renderStf = function (url) {
let ws
let ease
let banner
const canvas = document.createElement('canvas')
container.appendChild(canvas)
const show_loading = function () {
const ctx = canvas.getContext('2d')
ctx.fillStyle = "#ddd"
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.font = '36px "Microsoft Yahei"'
ctx.strokeStyle = '#06f'
ctx.strokeText('加载中...', canvas.width / 2 - 50, canvas.height / 2 - 20)
}
const createEase = function createEase () {
ws = new WebSocket(url + '?screen_width=' + quality.value)
ws.addEventListener('open', function () {
ws_list.push(ws)
show_loading()
})
return ease = Ease({
ws,
sender: muti.checked ? sender : undefined,
canvas,
// readonly: true,
onDevice: device => {
if (device && device.model) {
document.title = `${device.brand} ${device.model} | STF-EASE`
}
},
onBanner: _banner => {
banner = _banner
console.log(banner)
},
commands: defaultCommands.concat({
title: 'Input',
execute: () => new Promise(resolve => {
const str = prompt('input: ')
if (str) {
ws.send(ActionType.COMMAND + `: input text ` + str)
}
resolve(true)
})
}),
height: Math.min(document.documentElement.clientHeight - 10, 780),
onTouchMeta: function (meta) {
if (meta) {
// alert('minitouch初始化成功')
} else {
console.log('minitouch初始化失败!')
}
},
onClose: function () {
show_loading()
ws_list = ws_list.filter(t => t != ws)
setTimeout(createEase, 2000)
}
})
}
createEase()
quality.addEventListener('change', function (e) {
ws.send(`105: `)
})
muti.addEventListener('change', function () {
ease.setSender(muti.checked ? sender : ws.send.bind(ws))
})
addEventListener('resize', function () {
ease && ease.updateHeight(Math.min(document.documentElement.clientHeight - 10, 780))
})
}
urls.forEach(renderStf)
</script>
</body>
</html>
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )