mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2025-01-19 01:24:12 +01:00
perf: 🚀 合并无线连接及有线连接到设备列表
This commit is contained in:
parent
63a3de514b
commit
e84f24e816
@ -10,6 +10,11 @@ export default defineConfig({
|
||||
plugins: [externalizeDepsPlugin()],
|
||||
},
|
||||
preload: {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@resources': resolve('resources'),
|
||||
},
|
||||
},
|
||||
plugins: [externalizeDepsPlugin()],
|
||||
},
|
||||
renderer: {
|
||||
|
@ -4,7 +4,8 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@renderer/*": ["src/renderer/src/*"]
|
||||
"@renderer/*": ["src/renderer/src/*"],
|
||||
"@resources/*": ["resources/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ function createWindow() {
|
||||
webPreferences: {
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
sandbox: false,
|
||||
devTools: true,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { contextBridge } from 'electron'
|
||||
|
||||
export function addContext(key, value) {
|
||||
export function exposeContext(key, value) {
|
||||
if (process.contextIsolated) {
|
||||
try {
|
||||
contextBridge.exposeInMainWorld(key, value)
|
||||
|
@ -1,74 +1,4 @@
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
import { Adb } from '@devicefarmer/adbkit'
|
||||
import plugins from './plugins/index.js'
|
||||
import { exposeContext } from './helpers/index.js'
|
||||
|
||||
import scrcpyPath from '../../resources/core/scrcpy.exe?asset&asarUnpack'
|
||||
import adbPath from '../../resources/core/adb.exe?asset&asarUnpack'
|
||||
import { addContext } from './helpers/index.js'
|
||||
|
||||
const util = require('node:util')
|
||||
const exec = util.promisify(require('node:child_process').exec)
|
||||
|
||||
// Custom APIs for renderer
|
||||
const api = {}
|
||||
|
||||
// Use `contextBridge` APIs to expose Electron APIs to
|
||||
// renderer only if context isolation is enabled, otherwise
|
||||
// just add to the DOM global.
|
||||
addContext('electron', electronAPI)
|
||||
addContext('api', api)
|
||||
|
||||
addContext('adbkit', () => {
|
||||
const client = Adb.createClient({ bin: adbPath })
|
||||
console.log('client', client)
|
||||
|
||||
const getDevices = async () => await client.listDevicesWithPaths()
|
||||
const shell = async (id, command) => await client.getDevice(id).shell(command)
|
||||
const kill = async (...params) => await client.kill(...params)
|
||||
const connect = async (...params) => await client.connect(...params)
|
||||
const disconnect = async (...params) => await client.disconnect(...params)
|
||||
|
||||
const watch = async (callback) => {
|
||||
const tracker = await client.trackDevices()
|
||||
tracker.on('add', (device) => {
|
||||
callback(device)
|
||||
})
|
||||
|
||||
tracker.on('remove', (device) => {
|
||||
callback(device)
|
||||
})
|
||||
|
||||
tracker.on('end', (ret) => {
|
||||
callback(ret)
|
||||
})
|
||||
|
||||
tracker.on('error', (err) => {
|
||||
callback(err)
|
||||
})
|
||||
|
||||
const close = () => tracker.end()
|
||||
|
||||
return close
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
kill()
|
||||
})
|
||||
|
||||
return {
|
||||
getDevices,
|
||||
shell,
|
||||
kill,
|
||||
connect,
|
||||
disconnect,
|
||||
watch,
|
||||
}
|
||||
})
|
||||
|
||||
addContext('scrcpy', () => {
|
||||
const shell = command =>
|
||||
exec(`${scrcpyPath} ${command}`, { env: { ...process.env, ADB: adbPath } })
|
||||
|
||||
return {
|
||||
shell,
|
||||
}
|
||||
})
|
||||
plugins.install(exposeContext)
|
||||
|
53
src/preload/plugins/adbkit/index.js
Normal file
53
src/preload/plugins/adbkit/index.js
Normal file
@ -0,0 +1,53 @@
|
||||
import { Adb } from '@devicefarmer/adbkit'
|
||||
import adbPath from '@resources/core/adb.exe?asset&asarUnpack'
|
||||
|
||||
let client = null
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (client) {
|
||||
client.kill()
|
||||
}
|
||||
})
|
||||
|
||||
const getDevices = async () => await client.listDevicesWithPaths()
|
||||
const shell = async (id, command) => await client.getDevice(id).shell(command)
|
||||
const kill = async (...params) => await client.kill(...params)
|
||||
const connect = async (...params) => await client.connect(...params)
|
||||
const disconnect = async (...params) => await client.disconnect(...params)
|
||||
|
||||
const watch = async (callback) => {
|
||||
const tracker = await client.trackDevices()
|
||||
tracker.on('add', (device) => {
|
||||
callback(device)
|
||||
})
|
||||
|
||||
tracker.on('remove', (device) => {
|
||||
callback(device)
|
||||
})
|
||||
|
||||
tracker.on('end', (ret) => {
|
||||
callback(ret)
|
||||
})
|
||||
|
||||
tracker.on('error', (err) => {
|
||||
callback(err)
|
||||
})
|
||||
|
||||
const close = () => tracker.end()
|
||||
|
||||
return close
|
||||
}
|
||||
|
||||
export default () => {
|
||||
client = Adb.createClient({ bin: adbPath })
|
||||
console.log('client', client)
|
||||
|
||||
return {
|
||||
getDevices,
|
||||
shell,
|
||||
kill,
|
||||
connect,
|
||||
disconnect,
|
||||
watch,
|
||||
}
|
||||
}
|
3
src/preload/plugins/electron/index.js
Normal file
3
src/preload/plugins/electron/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
|
||||
export default () => electronAPI
|
11
src/preload/plugins/index.js
Normal file
11
src/preload/plugins/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
import electron from './electron/index.js'
|
||||
import adbkit from './adbkit/index.js'
|
||||
import scrcpy from './scrcpy/index.js'
|
||||
|
||||
export default {
|
||||
install(expose) {
|
||||
expose('electron', electron())
|
||||
expose('adbkit', adbkit())
|
||||
expose('scrcpy', scrcpy())
|
||||
},
|
||||
}
|
12
src/preload/plugins/scrcpy/index.js
Normal file
12
src/preload/plugins/scrcpy/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
import adbPath from '@resources/core/adb.exe?asset&asarUnpack'
|
||||
import scrcpyPath from '@resources/core/scrcpy.exe?asset&asarUnpack'
|
||||
|
||||
const util = require('node:util')
|
||||
const exec = util.promisify(require('node:child_process').exec)
|
||||
|
||||
const shell = command =>
|
||||
exec(`${scrcpyPath} ${command}`, { env: { ...process.env, ADB: adbPath } })
|
||||
|
||||
export default () => ({
|
||||
shell,
|
||||
})
|
@ -15,33 +15,27 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Wired from './components/Wired/index.vue'
|
||||
import Wireless from './components/Wireless/index.vue'
|
||||
import Devices from './components/Devices/index.vue'
|
||||
import Advanced from './components/Advanced/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Wired,
|
||||
Wireless,
|
||||
Devices,
|
||||
Advanced,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabsModel: [
|
||||
{
|
||||
label: '有线模式',
|
||||
prop: 'Wired',
|
||||
},
|
||||
{
|
||||
label: '无线模式',
|
||||
prop: 'Wireless',
|
||||
label: '设备列表',
|
||||
prop: 'Devices',
|
||||
},
|
||||
{
|
||||
label: '高级配置',
|
||||
prop: 'Advanced',
|
||||
},
|
||||
],
|
||||
activeTab: 'Wired',
|
||||
activeTab: 'Devices',
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="flex items-center flex-none space-x-2">
|
||||
<el-input v-model="formData.host" placeholder="192.168.0.1" class="w-72">
|
||||
<template #prepend>
|
||||
无线调试地址
|
||||
无线连接设备
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="text-gray-500 text-sm">
|
||||
@ -37,15 +37,18 @@
|
||||
<el-table-column prop="id" label="设备 ID" />
|
||||
<el-table-column prop="name" label="设备名称">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.$unauthorized" class="flex items-center">
|
||||
<el-tooltip content="请重新插拔设备并点击允许USB调试" placement="top-start">
|
||||
<div class="flex items-center">
|
||||
<el-tooltip
|
||||
v-if="row.$unauthorized"
|
||||
content="设备可能未授权成功,请重新插拔设备并点击允许USB调试"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-icon class="mr-1 text-red-600 text-lg">
|
||||
<WarningFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
设备未授权
|
||||
{{ row.name }}
|
||||
</div>
|
||||
<span v-else class="">{{ row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center">
|
||||
@ -53,11 +56,11 @@
|
||||
<el-button type="primary" :loading="row.$loading" @click="handleStart(row)">
|
||||
{{ row.$loading ? '镜像中' : '开始镜像' }}
|
||||
</el-button>
|
||||
<el-button :disabled="!row.$loading" type="default" @click="handleScreenUp(row)">
|
||||
<el-button type="default" @click="handleScreenUp(row)">
|
||||
点亮屏幕
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="!row.$loading"
|
||||
v-if="row.$wireless"
|
||||
type="danger"
|
||||
:loading="row.$stopLoading"
|
||||
@click="handleStop(row)"
|
||||
@ -146,18 +149,18 @@ export default {
|
||||
},
|
||||
async getDeviceData() {
|
||||
this.loading = true
|
||||
await sleep(500)
|
||||
await sleep()
|
||||
try {
|
||||
const data = await this.$adb.getDevices()
|
||||
this.deviceList = (data || [])
|
||||
.filter(item => isIPWithPort(item.id))
|
||||
.map(item => ({
|
||||
...item,
|
||||
name: item.model ? item.model.split(':')[1] : '未授权设备',
|
||||
$loading: false,
|
||||
$stopLoading: false,
|
||||
$unauthorized: item.type === 'unauthorized',
|
||||
}))
|
||||
this.deviceList = (data || []).map(item => ({
|
||||
...item,
|
||||
name: item.model ? item.model.split(':')[1] : '未授权设备',
|
||||
$loading: false,
|
||||
$stopLoading: false,
|
||||
$unauthorized: item.type === 'unauthorized',
|
||||
$wireless: isIPWithPort(item.id),
|
||||
}))
|
||||
|
||||
console.log('getDeviceData.data', this.deviceList)
|
||||
}
|
||||
catch (error) {
|
@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="flex items-center flex-none">
|
||||
<el-button type="primary" @click="getDeviceData">
|
||||
刷新设备
|
||||
</el-button>
|
||||
<el-button type="warning" @click="handleReset">
|
||||
重启服务
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="pt-4 flex-1 h-0 overflow-hidden">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:element-loading-text="loadingText"
|
||||
:data="deviceList"
|
||||
style="width: 100%"
|
||||
border
|
||||
height="100%"
|
||||
>
|
||||
<template #empty>
|
||||
<el-empty description="设备列表为空" />
|
||||
</template>
|
||||
<el-table-column prop="id" label="设备 ID" />
|
||||
<el-table-column prop="name" label="设备名称">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.$unauthorized" class="flex items-center">
|
||||
<el-tooltip content="请重新插拔设备并点击允许USB调试" placement="top-start">
|
||||
<el-icon class="mr-1 text-red-600 text-lg">
|
||||
<WarningFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
设备未授权
|
||||
</div>
|
||||
<span v-else class="">{{ row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" :loading="row.$loading" @click="handleStart(row)">
|
||||
{{ row.$loading ? '镜像中' : '开始镜像' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="!row.$loading"
|
||||
type="default"
|
||||
@click="handleScreenUp(row)"
|
||||
>
|
||||
点亮屏幕
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isIPWithPort, sleep } from '@renderer/utils/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
loadingText: '初始化中...',
|
||||
deviceList: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDeviceData()
|
||||
|
||||
this.$adb.watch(() => {
|
||||
this.getDeviceData()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleScreenUp(row) {
|
||||
this.$adb.shell(row.id, 'input keyevent KEYCODE_POWER')
|
||||
},
|
||||
handleReset() {
|
||||
this.$electron.ipcRenderer.send('restart-app')
|
||||
},
|
||||
async handleStart(row) {
|
||||
row.$loading = true
|
||||
try {
|
||||
await this.$scrcpy.shell(`-s ${row.id}`)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message)
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
row.$loading = false
|
||||
},
|
||||
async getDeviceData() {
|
||||
this.loading = true
|
||||
await sleep(500)
|
||||
try {
|
||||
const data = await this.$adb.getDevices()
|
||||
this.deviceList = (data || [])
|
||||
.filter(item => !isIPWithPort(item.id))
|
||||
.map(item => ({
|
||||
...item,
|
||||
name: item.model ? item.model.split(':')[1] : '未授权设备',
|
||||
$loading: false,
|
||||
$unauthorized: item.type === 'unauthorized',
|
||||
}))
|
||||
console.log('getDeviceData.data', this.deviceList)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message)
|
||||
this.$message.warning(error.message)
|
||||
this.deviceList = []
|
||||
}
|
||||
this.loading = false
|
||||
this.loadingText = '正在获取设备列表...'
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -11,7 +11,7 @@ const app = createApp(App)
|
||||
app.use(plugins)
|
||||
|
||||
app.config.globalProperties.$electron = window.electron
|
||||
app.config.globalProperties.$adb = window.adbkit()
|
||||
app.config.globalProperties.$scrcpy = window.scrcpy()
|
||||
app.config.globalProperties.$adb = window.adbkit
|
||||
app.config.globalProperties.$scrcpy = window.scrcpy
|
||||
|
||||
app.mount('#app')
|
||||
|
Loading…
x
Reference in New Issue
Block a user