Skip to content

Commit

Permalink
feat: 🎉 Support batch execution script function
Browse files Browse the repository at this point in the history
  • Loading branch information
viarotel committed Jul 13, 2024
1 parent 2013413 commit 8097022
Show file tree
Hide file tree
Showing 21 changed files with 625 additions and 316 deletions.
3 changes: 2 additions & 1 deletion .eslintrc-auto-import.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
"watchSyncEffect": true,
"ElMessage": true
}
}
17 changes: 10 additions & 7 deletions README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ Windows 及 Linux 端内部集成了 Gnirehtet, 用于提供 PC 到安卓设

### 批量处理

- 批量截取屏幕
- 批量安装应用
- 批量文件管理
- 批量执行脚本

### 控制模式

Expand All @@ -99,6 +102,7 @@ Windows 及 Linux 端内部集成了 Gnirehtet, 用于提供 PC 到安卓设
- 重启设备
- 安装应用
- 文件管理
- 执行脚本
- 反向供网(Gnirehtet)
- 多屏协同

Expand Down Expand Up @@ -204,13 +208,12 @@ Windows 及 Linux 端内部集成了 Gnirehtet, 用于提供 PC 到安卓设
15. 支持批量连接历史设备功能 ✅
16. 支持使用内置终端执行自定义命令 ✅
17. 支持设备自动执行镜像 ✅
18. 支持常用批量功能 ✅
19. 支持灵活启动镜像 ✅
20. 支持更多批量处理功能 🚧
21. 支持对设备进行分组 🚧
22. 添加文件传输助手功能 🚧
23. 支持通过界面从设备下载选中的文件 🚧
24. 添加对游戏的增强功能,如游戏键位映射 🚧
18. 支持灵活启动镜像 ✅
19. 支持常用批量功能 ✅
20. 支持对设备进行分组 🚧
21. 添加文件传输助手功能 🚧
22. 支持通过界面从设备下载选中的文件 🚧
23. 添加对游戏的增强功能,如游戏键位映射 🚧

## 常见问题

Expand Down
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ Refer to [scrcpy/doc/shortcuts](https://github.com/Genymobile/scrcpy/blob/master

### Batch Processing

- Batch installation application
- Batch Interception Screen
- Batch Installation Application
- Batch File Management
- Batch Execution Script

### Control Model

Expand All @@ -97,6 +100,7 @@ Refer to [scrcpy/doc/shortcuts](https://github.com/Genymobile/scrcpy/blob/master
- Reboot
- Install APP
- File Manager
- Execution Script
- Gnirehtet
- Mirror Group

Expand Down Expand Up @@ -201,14 +205,13 @@ Refer to [scrcpy/doc/shortcuts](https://github.com/Genymobile/scrcpy/blob/master
14. Add more features to device interaction bar: file push, screen rotation, audio control etc ✅
15. Support bulk connecting to historical devices ✅
16. Support to use built-in terminals to execute custom commands ✅
17. Supports automatic execution of mirror on devices ✅
18. Support common batch processing function ✅
19. Support for custom startup mirroring ✅
20. Support more batch processing functions 🚧
21. Support the device to group 🚧
22. Add file transmission assistant function 🚧
23. Support GUI-based selective file downloads from devices 🚧
24. Add game enhancement features such as game keyboard mapping 🚧
17. Support automatic execution of mirror on devices ✅
18. Support for custom startup mirroring ✅
19. Support common batch processing function ✅
20. Support the device to group 🚧
21. Add file transmission assistant function 🚧
22. Support GUI-based selective file downloads from devices 🚧
23. Add game enhancement features such as game keyboard mapping 🚧

## FAQ

Expand Down
1 change: 1 addition & 0 deletions auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElMessage: typeof import('element-plus/es')['ElMessage']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<div class="" @click="handleClick">
<slot />
<slot v-bind="{ loading }" />
<ApplicationProxy ref="applicationProxyRef" />
</div>
</template>

<script>
import ApplicationProxy from '$/components/Device/components/ControlBar/Application/index.vue'
import { sleep } from '$/utils'
import { allSettled } from '$/utils'
export default {
components: {
Expand All @@ -19,13 +19,42 @@ export default {
default: () => [],
},
},
data() {
return {
loading: false,
}
},
methods: {
async handleClick() {
for (let index = 0; index < this.devices.length; index++) {
const item = this.devices[index]
await this.$refs.applicationProxyRef.invoke(item)
await sleep(1 * 1000)
let files = null
try {
files = await this.$electron.ipcRenderer.invoke('show-open-dialog', {
properties: ['openFile', 'multiSelections'],
filters: [
{
name: this.$t('device.control.install.placeholder'),
extensions: ['apk'],
},
],
})
}
catch (error) {
if (error.message) {
const message
= error.message?.match(/Error: (.*)/)?.[1] || error.message
this.$message.warning(message)
}
return false
}
this.loading = true
await allSettled(this.devices, (item) => {
return this.$refs.applicationProxyRef.invoke(item, { files })
})
this.loading = false
},
},
}
Expand Down
71 changes: 71 additions & 0 deletions src/components/Device/components/BatchActions/FileManage/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<el-dropdown :hide-on-click="false">
<div class="">
<slot :loading="loading" />
<FileManageProxy ref="fileManageProxyRef" />
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handlePush(devices)">
<span class="" title="/sdcard/Download/">
{{ $t('device.control.file.push') }}
</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import FileManageProxy from '$/components/Device/components/ControlBar/FileManage/index.vue'
import { selectAndSendFileToDevice } from '$/utils/device/index.js'
import { allSettled } from '$/utils'
const props = defineProps({
devices: {
type: Object,
default: () => null,
},
})
const loading = ref(false)
const fileManageProxyRef = ref(null)
async function handlePush(devices) {
let files = null
try {
files = await window.electron.ipcRenderer.invoke('show-open-dialog', {
properties: ['openFile', 'multiSelections'],
filters: [
{
name: window.t('device.control.file.push.placeholder'),
extensions: ['*'],
},
],
})
}
catch (error) {
if (error.message) {
const message = error.message?.match(/Error: (.*)/)?.[1] || error.message
ElMessage.warning(message)
}
return false
}
loading.value = true
await allSettled(devices, (item) => {
return fileManageProxyRef.value.handlePush(item, { files })
})
ElMessage.success(window.t('common.success.batch'))
loading.value = false
}
</script>
<style></style>
21 changes: 14 additions & 7 deletions src/components/Device/components/BatchActions/Screenshot/index.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<div class="" @click="handleClick">
<slot />
<slot v-bind="{ loading }" />
<ScreenshotProxy ref="screenshotProxyRef" />
</div>
</template>

<script>
import ScreenshotProxy from '$/components/Device/components/ControlBar/Screenshot/index.vue'
import { sleep } from '$/utils'
import { allSettled, sleep } from '$/utils'
export default {
components: {
Expand All @@ -19,13 +19,20 @@ export default {
default: () => [],
},
},
data() {
return {
loading: false,
}
},
methods: {
async handleClick() {
for (let index = 0; index < this.devices.length; index++) {
const item = this.devices[index]
await this.$refs.screenshotProxyRef.invoke(item)
await sleep(1 * 1000)
}
this.loading = true
await allSettled(this.devices, (item) => {
return this.$refs.screenshotProxyRef.invoke(item)
})
this.loading = false
},
},
}
Expand Down
83 changes: 83 additions & 0 deletions src/components/Device/components/BatchActions/Shell/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<template>
<div class="" @click="handleClick(devices)">
<slot v-bind="{ loading }" />
</div>
</template>

<script setup>
import { ElMessage, ElMessageBox } from 'element-plus'
import { selectAndSendFileToDevice } from '$/utils/device/index.js'
import { allSettled } from '$/utils'
const props = defineProps({
devices: {
type: Object,
default: () => null,
},
})
const loading = ref(false)
async function handleClick(devices) {
let files = null
try {
files = await window.electron.ipcRenderer.invoke('show-open-dialog', {
properties: ['openFile'],
filters: [
{
name: window.t('device.control.shell.select'),
extensions: ['sh'],
},
],
})
}
catch (error) {
if (error.message) {
const message = error.message?.match(/Error: (.*)/)?.[1]
ElMessage.warning(message || error.message)
}
return false
}
loading.value = true
const failFiles = []
await allSettled(devices, async (device) => {
const successFiles = await selectAndSendFileToDevice(device.id, {
files,
loadingText: window.t('device.control.shell.push.loading'),
successText: window.t('device.control.shell.push.success'),
}).catch((e) => {
console.warn(e.message)
failFiles.push(e.message)
})
const filePath = successFiles?.[0]
if (filePath) {
window.adbkit.deviceShell(device.id, `sh ${filePath}`)
}
})
if (failFiles.length) {
ElMessageBox.alert(
`<div>${failFiles.map(text => `${text}<br/>`).join('')}</div>`,
window.t('common.tips'),
{
type: 'warning',
dangerouslyUseHTMLString: true,
},
)
loading.value = false
return false
}
await ElMessage.success(window.t('device.control.shell.success'))
loading.value = false
}
</script>
<style></style>
Loading

0 comments on commit 8097022

Please sign in to comment.