代码拉取完成,页面将自动刷新
同步操作将从 云香水识/stf-ease 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<!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}`).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}`).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 "/static/bundle.js"
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 createEase = function createEase () {
ws = new WebSocket(url + '?screen_width=' + quality.value)
ws.addEventListener('open', function () {
ws_list.push(ws)
})
return ease = Ease({
ws,
sender: muti.checked ? sender : undefined,
canvas,
// readonly: true,
onDevice: device => {
console.log(device)
},
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 () {
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)
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>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。