mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-30 18:24:27 +01:00
perf: 🚀 Add File push function
This commit is contained in:
parent
b40bdcfd7d
commit
70f8b469b9
11
README-CN.md
11
README-CN.md
@ -175,12 +175,13 @@ Windows 及 Linux 端内部集成了 Gnirehtet, 用于提供 PC 到安卓设
|
||||
11. 添加 Gnirehtet 反向供网功能 ✅
|
||||
12. 添加新的相机镜像相关功能 ✅
|
||||
13. 更好的多屏协同 ✅
|
||||
14. 设备交互栏添加更多功能:文件传输、旋转屏幕、音频控制等功能 🚧
|
||||
14. 设备交互栏添加更多功能:文件推送、旋转屏幕、音频控制等功能 ✅
|
||||
15. 支持批量连接历史设备功能 🚧
|
||||
16. 支持对设备进行分组,以及按组进行批量操作 🚧
|
||||
17. 添加独立的剪切板同步功能 🚧
|
||||
18. 支持自定义执行 Adb 脚本 🚧
|
||||
19. 添加对游戏的增强功能,如游戏键位映射 🚧
|
||||
16. 添加独立的剪切板同步功能 🚧
|
||||
17. 支持通过界面从设备下载选中的文件 🚧
|
||||
18. 支持对设备进行分组,以及按组进行批量操作 🚧
|
||||
19. 支持自定义执行 Adb 脚本 🚧
|
||||
20. 添加对游戏的增强功能,如游戏键位映射 🚧
|
||||
|
||||
## 常见问题
|
||||
|
||||
|
11
README.md
11
README.md
@ -173,12 +173,13 @@ Refer to [scrcpy/doc/shortcuts](https://github.com/Genymobile/scrcpy/blob/master
|
||||
11. Add Gnirehtet reverse network function ✅
|
||||
12. Add new camera mirror related features ✅
|
||||
13. Better multi -screen collaboration ✅
|
||||
14. Add more features to device interaction bar: file transfer, screen rotation, audio control etc 🚧
|
||||
14. Add more features to device interaction bar: file push, screen rotation, audio control etc ✅
|
||||
15. Support bulk connecting to historical devices 🚧
|
||||
16. Support grouping devices and bulk operations by group 🚧
|
||||
17. Add standalone clipboard sync feature 🚧
|
||||
18. Support custom Adb script execution 🚧
|
||||
19. Add game enhancement features such as game keyboard mapping 🚧
|
||||
16. Add standalone clipboard sync feature 🚧
|
||||
17. Support GUI-based selective file downloads from devices 🚧
|
||||
18. Support grouping devices and bulk operations by group 🚧
|
||||
19. Support custom Adb script execution 🚧
|
||||
20. Add game enhancement features such as game keyboard mapping 🚧
|
||||
|
||||
## FAQ
|
||||
|
||||
|
@ -132,6 +132,30 @@ const clearOverlayDisplayDevices = async (deviceId) => {
|
||||
)
|
||||
}
|
||||
|
||||
const push = async (
|
||||
id,
|
||||
filePath,
|
||||
{ progress, savePath = `/sdcard/Download/${path.basename(filePath)}` } = {},
|
||||
) => {
|
||||
const res = await client.getDevice(id).push(filePath, savePath)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
res.on('progress', (stats) => {
|
||||
console.log('adb.push.progress', stats)
|
||||
|
||||
progress?.(stats)
|
||||
})
|
||||
|
||||
res.on('end', (ret) => {
|
||||
resolve(ret)
|
||||
})
|
||||
|
||||
res.on('error', (err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const watch = async (callback) => {
|
||||
const tracker = await client.trackDevices()
|
||||
tracker.on('add', async (ret) => {
|
||||
@ -182,6 +206,7 @@ export default () => {
|
||||
version,
|
||||
display,
|
||||
clearOverlayDisplayDevices,
|
||||
push,
|
||||
watch,
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<el-dropdown :hide-on-click="false">
|
||||
<div class="">
|
||||
<slot :loading="loading" />
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="handlePush">
|
||||
{{ $t("device.control.file.push") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async handlePush() {
|
||||
this.loading = true
|
||||
let files = null
|
||||
|
||||
try {
|
||||
files = await this.$electron.ipcRenderer.invoke('show-open-dialog', {
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: [
|
||||
{
|
||||
name: this.$t('device.control.file.push.placeholder'),
|
||||
extensions: ['*'],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
if (!files) {
|
||||
this.loading = false
|
||||
return false
|
||||
}
|
||||
|
||||
let failCount = 0
|
||||
|
||||
for (let index = 0; index < files.length; index++) {
|
||||
const item = files[index]
|
||||
await this.$adb.push(this.device.id, item).catch((e) => {
|
||||
console.warn(e)
|
||||
++failCount
|
||||
})
|
||||
}
|
||||
|
||||
this.loading = false
|
||||
|
||||
const totalCount = files.length
|
||||
const successCount = totalCount - failCount
|
||||
|
||||
if (successCount) {
|
||||
if (totalCount > 1) {
|
||||
this.$message.success(
|
||||
this.$t('device.control.file.push.success', {
|
||||
deviceName: this.device.$name,
|
||||
totalCount,
|
||||
successCount,
|
||||
failCount,
|
||||
}),
|
||||
)
|
||||
}
|
||||
else {
|
||||
this.$message.success(
|
||||
this.$t('device.control.file.push.success.single', {
|
||||
deviceName: this.device.$name,
|
||||
}),
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.$message.warning(this.$t('device.control.file.push.error'))
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -41,7 +41,9 @@ export default {
|
||||
try {
|
||||
await this.$gnirehtet.run(device.id)
|
||||
await sleep()
|
||||
this.$message.success(this.$t('device.control.gnirehtet.success'))
|
||||
this.$message.success(
|
||||
this.$t('device.control.gnirehtet.start.success'),
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
this.$message.warning(error.message || 'Start service failure')
|
||||
|
@ -52,6 +52,7 @@ import Gnirehtet from './Gnirehtet/index.vue'
|
||||
import MirrorGroup from './MirrorGroup/index.vue'
|
||||
import Rotation from './Rotation/index.vue'
|
||||
import Volume from './Volume/index.vue'
|
||||
import FileManage from './FileManage/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -61,6 +62,7 @@ export default {
|
||||
MirrorGroup,
|
||||
Rotation,
|
||||
Volume,
|
||||
FileManage,
|
||||
},
|
||||
props: {
|
||||
device: {
|
||||
@ -113,7 +115,6 @@ export default {
|
||||
label: 'device.control.capture',
|
||||
elIcon: 'Crop',
|
||||
component: 'Screenshot',
|
||||
tips: '',
|
||||
},
|
||||
{
|
||||
label: 'device.control.reboot',
|
||||
@ -124,7 +125,11 @@ export default {
|
||||
label: 'device.control.install',
|
||||
svgIcon: 'install',
|
||||
component: 'AppInstall',
|
||||
tips: '',
|
||||
},
|
||||
{
|
||||
label: 'device.control.file.name',
|
||||
svgIcon: 'file-send',
|
||||
component: 'FileManage',
|
||||
},
|
||||
{
|
||||
label: 'device.control.gnirehtet',
|
||||
|
1
src/icons/svg/file-send.svg
Normal file
1
src/icons/svg/file-send.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"/><path fill="currentColor" d="M9.52 3a2 2 0 0 1 1.561.75l1.4 1.75H20a2 2 0 0 1 2 2V19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5.52Zm0 2H4v14h16V7.5h-7.52a2 2 0 0 1-1.561-.75L9.519 5Zm3.187 5.173l2.121 2.121a1 1 0 1 1-1.414 1.414L13 13.294V16a1 1 0 1 1-2 0v-2.706l-.414.414a1 1 0 1 1-1.414-1.414l2.12-2.121a1 1 0 0 1 1.415 0Z"/></g></svg>
|
After Width: | Height: | Size: 1013 B |
@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1697530402297" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1513" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M56.888889 284.444444h853.333333v682.666667H56.888889V284.444444z m56.888889 56.888889v568.888889h739.555555V341.333333H113.777778zM199.111111 170.666667L125.155556 284.444444H56.888889l113.777778-170.666666h625.777777l113.777778 170.666666h-68.266666l-73.955556-113.777777h-568.888889zM125.155556 284.444444H56.888889l113.777778-170.666666h625.777777l113.777778 170.666666h-68.266666l-73.955556-113.777777h-568.888889L125.155556 284.444444z" p-id="1514"/><path d="M227.555556 603.022222l39.822222-34.133333 221.866666 193.422222 216.177778-193.422222 39.822222 34.133333-256 227.555556z" p-id="1515"/><path d="M455.111111 398.222222h56.888889v369.777778H455.111111z" p-id="1516"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 48 48"><g fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="4"><path stroke-linecap="round" d="M41.4 11.551L36.333 5H11.667l-5.083 6.551"/><path d="M6 13a2 2 0 0 1 2-2h32a2 2 0 0 1 2 2v27a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V13Z"/><path stroke-linecap="round" d="m32 27l-8 8l-8-8m7.992-8v16"/></g></svg>
|
Before Width: | Height: | Size: 1020 B After Width: | Height: | Size: 396 B |
@ -9,6 +9,7 @@
|
||||
"common.tips": "Tips",
|
||||
"common.open": "Open",
|
||||
"common.input.placeholder": "Please input",
|
||||
"common.success": "Operation successful",
|
||||
|
||||
"close.quit": "Quit",
|
||||
"close.quit.cancel": "Cancel quit",
|
||||
@ -81,6 +82,12 @@
|
||||
"device.control.install.success": "Successfully installed {totalCount} apps to {deviceName}, {successCount} succeeded, {failCount} failed",
|
||||
"device.control.install.success.single": "Successfully installed app to {deviceName}",
|
||||
"device.control.install.error": "Install failed, please check app and try again",
|
||||
"device.control.file.name": "File Manager",
|
||||
"device.control.file.push": "Push File",
|
||||
"device.control.file.push.placeholder": "Please select the file to push",
|
||||
"device.control.file.push.success": "Successfully pushed {totalCount} files to {deviceName}, {successCount} succeeded, {failCount} failed",
|
||||
"device.control.file.push.success.single": "Successfully pushed the file to {deviceName}",
|
||||
"device.control.file.push.error": "Failed to push the file, please check the file and try again",
|
||||
"device.control.capture": "Screenshot",
|
||||
"device.control.capture.progress": "Capturing screenshot for {deviceName}...",
|
||||
"device.control.capture.success.message": "Open screenshot location?",
|
||||
@ -95,8 +102,10 @@
|
||||
"device.control.switch": "Switch",
|
||||
"device.control.gnirehtet": "Gnirehtet",
|
||||
"device.control.gnirehtet.tips": "Gnirehtet provides reverse tethering for Android; Note: Initial connection requires authorization on the device.",
|
||||
"device.control.gnirehtet.progress": "Starting Gnirehtet reverse tethering service...",
|
||||
"device.control.gnirehtet.success": "Gnirehtet reverse tethering feature started successfully",
|
||||
"device.control.gnirehtet.start": "Start Service",
|
||||
"device.control.gnirehtet.start.success": "Gnirehtet reverse tethering feature started successfully",
|
||||
"device.control.gnirehtet.stop": "Stop Service",
|
||||
"device.control.gnirehtet.stop.success": "Service stopped successfully",
|
||||
"device.control.mirror-group.name": "Mirror Group",
|
||||
"device.control.mirror-group.tips": "When enabled, can mirror multiple simulated secondary displays and achieve multi-screen collaboration by operating each mirrored window. Note this requires ROM support and desktop mode enabled.",
|
||||
"device.control.mirror-group.open": "Open {num} windows",
|
||||
|
@ -80,6 +80,12 @@
|
||||
"device.control.install.success": "已成功将应用安装到 {deviceName} 中,共 {totalCount}个,成功 {successCount}个,失败 {failCount}个",
|
||||
"device.control.install.success.single": "已成功将应用安装到 {deviceName} 中",
|
||||
"device.control.install.error": "安装应用失败,请检查安装包后重试",
|
||||
"device.control.file.name": "文件管理",
|
||||
"device.control.file.push": "推送文件",
|
||||
"device.control.file.push.placeholder": "请选择要推送的文件",
|
||||
"device.control.file.push.success": "已成功将文件推送到 {deviceName} 中,共 {totalCount}个,成功 {successCount}个,失败 {failCount}个",
|
||||
"device.control.file.push.success.single": "已成功将文件推送到 {deviceName} 中",
|
||||
"device.control.file.push.error": "推送文件失败,请检查文件后重试",
|
||||
"device.control.capture": "截取屏幕",
|
||||
"device.control.capture.progress": "正在截取 {deviceName} 的屏幕快照...",
|
||||
"device.control.capture.success.message": "是否前往截屏位置进行查看?",
|
||||
@ -94,9 +100,8 @@
|
||||
"device.control.switch": "切换键",
|
||||
"device.control.gnirehtet": "反向供网",
|
||||
"device.control.gnirehtet.tips": "使用 Gnirehtet 为 Android 提供反向网络共享;注意:首次连接需要在设备上进行授权",
|
||||
"device.control.gnirehtet.progress": "正在启动 Gnirehtet 反向供网服务中...",
|
||||
"device.control.gnirehtet.success": "Gnirehtet 反向网络共享功能启动成功",
|
||||
"device.control.gnirehtet.start": "启动服务",
|
||||
"device.control.gnirehtet.start.success": "Gnirehtet 反向网络共享功能启动成功",
|
||||
"device.control.gnirehtet.stop": "停止服务",
|
||||
"device.control.gnirehtet.stop.success": "停止服务成功",
|
||||
"device.control.mirror-group.name": "多屏协同",
|
||||
|
Loading…
Reference in New Issue
Block a user