mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2025-02-07 14:41:19 +01:00
feat: 🚀 添加基本的无线连接功能
This commit is contained in:
parent
647a0c5606
commit
6dd2db9da9
@ -1,15 +0,0 @@
|
|||||||
/* eslint-env node */
|
|
||||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:vue/vue3-recommended',
|
|
||||||
'@electron-toolkit',
|
|
||||||
'@vue/eslint-config-prettier',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'vue/require-default-prop': 'off',
|
|
||||||
'vue/multi-word-component-names': 'off',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,3 +1,6 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ['@electron-toolkit', '@viarotel-org'],
|
extends: ['@electron-toolkit', '@viarotel-org'],
|
||||||
rules: {
|
rules: {
|
||||||
|
@ -3,6 +3,8 @@ import { BrowserWindow, app, shell } from 'electron'
|
|||||||
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
|
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
|
||||||
import icon from '../../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset'
|
||||||
|
|
||||||
|
import './ipc/index.js'
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
const mainWindow = new BrowserWindow({
|
const mainWindow = new BrowserWindow({
|
||||||
|
6
src/main/ipc/index.js
Normal file
6
src/main/ipc/index.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { app, ipcMain } from 'electron'
|
||||||
|
|
||||||
|
ipcMain.on('restart-app', () => {
|
||||||
|
app.relaunch()
|
||||||
|
app.quit()
|
||||||
|
})
|
@ -22,11 +22,44 @@ addContext('adbkit', () => {
|
|||||||
|
|
||||||
const getDevices = async () => await client.listDevicesWithPaths()
|
const getDevices = async () => await client.listDevicesWithPaths()
|
||||||
const shell = async (id, command) => await client.getDevice(id).shell(command)
|
const shell = async (id, command) => await client.getDevice(id).shell(command)
|
||||||
const kill = async () => await client.kill()
|
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 {
|
return {
|
||||||
getDevices,
|
getDevices,
|
||||||
shell,
|
shell,
|
||||||
kill,
|
kill,
|
||||||
|
connect,
|
||||||
|
disconnect,
|
||||||
|
watch,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:name="item.prop"
|
:name="item.prop"
|
||||||
|
lazy
|
||||||
>
|
>
|
||||||
<component :is="item.prop" />
|
<component :is="item.prop" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="">
|
<div class="h-full flex flex-col">
|
||||||
<div class="flex">
|
<div class="flex items-center flex-none">
|
||||||
<el-button type="primary" @click="handleFind">
|
<el-button type="primary" @click="getDeviceData">
|
||||||
刷新设备
|
刷新设备
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="warning" :loading="stopLoading" @click="handleReset">
|
<el-button type="warning" @click="handleReset">
|
||||||
{{ stopLoading ? '重置服务中' : '重置服务' }}
|
重启服务
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-4">
|
<div class="pt-4 flex-1 h-0 overflow-hidden">
|
||||||
<el-table v-loading="loading" :data="deviceList" style="width: 100%" border>
|
<el-table v-loading="loading" :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="id" label="设备 ID" />
|
||||||
<el-table-column prop="name" label="设备名称">
|
<el-table-column prop="name" label="设备名称">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@ -24,7 +27,7 @@
|
|||||||
<span v-else class="">{{ row.name }}</span>
|
<span v-else class="">{{ row.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="200" align="center">
|
<el-table-column label="操作" width="300" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" :loading="row.$loading" @click="handleStart(row)">
|
<el-button type="primary" :loading="row.$loading" @click="handleStart(row)">
|
||||||
{{ row.$loading ? '运行中' : '连接设备' }}
|
{{ row.$loading ? '运行中' : '连接设备' }}
|
||||||
@ -37,27 +40,34 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { sleep } from '@renderer/utils/index.js'
|
import { isIPWithPort, sleep } from '@renderer/utils/index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
stopLoading: false,
|
|
||||||
deviceList: [],
|
deviceList: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getDeviceData()
|
this.getDeviceData()
|
||||||
|
|
||||||
|
this.$adb.watch(() => {
|
||||||
|
this.getDeviceData()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleReset() {
|
||||||
|
this.$electron.ipcRenderer.send('restart-app')
|
||||||
|
},
|
||||||
async handleStart(row) {
|
async handleStart(row) {
|
||||||
row.$loading = true
|
row.$loading = true
|
||||||
try {
|
try {
|
||||||
await this.$scrcpy.shell(`-s ${row.id}`)
|
await this.$scrcpy.shell(`-s ${row.id}`)
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
this.$message.error(`${error.message}`)
|
if (error.message)
|
||||||
|
this.$message.warning(error.message)
|
||||||
}
|
}
|
||||||
row.$loading = false
|
row.$loading = false
|
||||||
},
|
},
|
||||||
@ -65,36 +75,24 @@ export default {
|
|||||||
this.loading = true
|
this.loading = true
|
||||||
await sleep(500)
|
await sleep(500)
|
||||||
try {
|
try {
|
||||||
const data = await this.$adb.getDevices().catch(e => console.warn(e))
|
const data = await this.$adb.getDevices()
|
||||||
console.log('getDeviceData.data', data)
|
this.deviceList = (data || [])
|
||||||
this.deviceList = data.map(item => ({
|
.filter(item => !isIPWithPort(item.id))
|
||||||
...item,
|
.map(item => ({
|
||||||
name: item.model ? item.model.split(':')[1] : '未授权设备',
|
...item,
|
||||||
$loading: false,
|
name: item.model ? item.model.split(':')[1] : '未授权设备',
|
||||||
$unauthorized: item.type === 'unauthorized',
|
$loading: false,
|
||||||
}))
|
$unauthorized: item.type === 'unauthorized',
|
||||||
|
}))
|
||||||
|
console.log('getDeviceData.data', this.deviceList)
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.warn('error', error.message)
|
if (error.message)
|
||||||
|
this.$message.warning(error.message)
|
||||||
|
this.deviceList = []
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
},
|
},
|
||||||
handleFind() {
|
|
||||||
this.getDeviceData()
|
|
||||||
},
|
|
||||||
async handleReset() {
|
|
||||||
this.stopLoading = true
|
|
||||||
try {
|
|
||||||
await this.$adb.kill()
|
|
||||||
await sleep(2000)
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.warn('error', error.message)
|
|
||||||
}
|
|
||||||
this.stopLoading = false
|
|
||||||
this.$message.success('重置服务状态成功')
|
|
||||||
this.handleFind()
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,9 +1,152 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class=""></div>
|
<div class="h-full flex flex-col">
|
||||||
|
<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">
|
||||||
|
:
|
||||||
|
</div>
|
||||||
|
<el-input v-model.number="formData.port" type="number" placeholder="5555" class="w-24">
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<el-button type="primary" :loading="connectLoading" @click="handleConnect">
|
||||||
|
开始连接
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @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" :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 type="danger" :loading="row.$stopLoading" @click="handleStop(row)">
|
||||||
|
{{ row.$stopLoading ? '断开中' : '断开连接' }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {}
|
import { isIPWithPort, sleep } from '@renderer/utils/index.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
connectLoading: false,
|
||||||
|
deviceList: [],
|
||||||
|
formData: {
|
||||||
|
host: '',
|
||||||
|
port: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getDeviceData()
|
||||||
|
|
||||||
|
this.$adb.watch(() => {
|
||||||
|
this.getDeviceData()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleReset() {
|
||||||
|
this.$electron.ipcRenderer.send('restart-app')
|
||||||
|
},
|
||||||
|
async handleConnect() {
|
||||||
|
if (!this.formData.host) {
|
||||||
|
this.$message.warning('无线调试地址不能为空')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.connectLoading = true
|
||||||
|
try {
|
||||||
|
await this.$adb.connect(this.formData.host, this.formData.port || 5555)
|
||||||
|
this.$message.success('连接设备成功')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.message)
|
||||||
|
this.$message.warning(error.message)
|
||||||
|
}
|
||||||
|
this.connectLoading = false
|
||||||
|
},
|
||||||
|
async handleStop(row) {
|
||||||
|
row.$stopLoading = true
|
||||||
|
const [host, port] = row.id.split(':')
|
||||||
|
try {
|
||||||
|
await this.$adb.disconnect(host, port)
|
||||||
|
await sleep()
|
||||||
|
this.$message.success('断开连接成功')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.message)
|
||||||
|
this.$message.warning(error.message)
|
||||||
|
}
|
||||||
|
row.$stopLoading = false
|
||||||
|
},
|
||||||
|
async handleStart(row) {
|
||||||
|
row.$loading = true
|
||||||
|
try {
|
||||||
|
await this.$scrcpy.shell(`--serial=${row.id}`)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
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,
|
||||||
|
$stopLoading: 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
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style></style>
|
||||||
|
@ -10,6 +10,7 @@ const app = createApp(App)
|
|||||||
|
|
||||||
app.use(plugins)
|
app.use(plugins)
|
||||||
|
|
||||||
|
app.config.globalProperties.$electron = window.electron
|
||||||
app.config.globalProperties.$adb = window.adbkit()
|
app.config.globalProperties.$adb = window.adbkit()
|
||||||
app.config.globalProperties.$scrcpy = window.scrcpy()
|
app.config.globalProperties.$scrcpy = window.scrcpy()
|
||||||
|
|
||||||
|
@ -7,3 +7,10 @@ export function sleep(time = 1000) {
|
|||||||
setTimeout(() => resolve(true), time)
|
setTimeout(() => resolve(true), time)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isIPWithPort(ip) {
|
||||||
|
const regex
|
||||||
|
= /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d):([1-9]|[1-9]\d{1,3}|[1-6][0-5][0-5][0-3][0-5])$/
|
||||||
|
|
||||||
|
return regex.test(ip)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user