mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-23 23:21:02 +01:00
feat: ✨ Supports starting applications for mirroring
This commit is contained in:
parent
ce6ea8e39d
commit
d19e781471
@ -28,7 +28,7 @@
|
|||||||
icon="ArrowDown"
|
icon="ArrowDown"
|
||||||
@click="switchDevice"
|
@click="switchDevice"
|
||||||
>
|
>
|
||||||
<span class="mr-2">{{ deviceInfo.$remark || deviceInfo.$name }}</span>
|
<span class="mr-2">{{ deviceName }}</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -79,6 +79,8 @@ const deviceInfo = ref({})
|
|||||||
|
|
||||||
const deviceList = ref([])
|
const deviceList = ref([])
|
||||||
|
|
||||||
|
const deviceName = computed(() => deviceStore.getLabel(deviceInfo.value, ({ deviceName }) => deviceName))
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
window.electron.ipcRenderer.send('hide-active-window')
|
window.electron.ipcRenderer.send('hide-active-window')
|
||||||
}
|
}
|
||||||
@ -88,7 +90,17 @@ async function switchDevice(e) {
|
|||||||
|
|
||||||
const data = await deviceStore.getList()
|
const data = await deviceStore.getList()
|
||||||
|
|
||||||
window.electron.ipcRenderer.send('open-control-device-menu', data)
|
const options = data.map((item) => {
|
||||||
|
return {
|
||||||
|
label: deviceStore.getLabel(item, ({ deviceName }) => deviceName),
|
||||||
|
value: item,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.send('open-system-menu', {
|
||||||
|
channel: 'device-change',
|
||||||
|
options,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
|
||||||
import { openControlWindow } from '$control/electron/helpers/index.js'
|
|
||||||
|
|
||||||
export default function (controlWindow) {
|
|
||||||
ipcMain.on('open-control-device-menu', (event, deviceList) => {
|
|
||||||
const template = deviceList.map((item) => {
|
|
||||||
let label = item.$remark || item.$name
|
|
||||||
|
|
||||||
if (item.$wifi) {
|
|
||||||
label += ` (WIFI)`
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
label,
|
|
||||||
click: () => {
|
|
||||||
openControlWindow(controlWindow, item)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const menu = Menu.buildFromTemplate(template)
|
|
||||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,4 +1 @@
|
|||||||
export { default as devices } from './devices/index.js'
|
export { default as menu } from './menu/index.js'
|
||||||
export { default as gnirehtet } from './gnirehtet/index.js'
|
|
||||||
export { default as rotation } from './rotation/index.js'
|
|
||||||
export { default as volume } from './volume/index.js'
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
||||||
|
|
||||||
export default function (controlWindow) {
|
export default function (controlWindow) {
|
||||||
ipcMain.on('open-device-gnirehtet-menu', openDeviceGnirehtetMenu)
|
ipcMain.on('open-system-menu', openSystemMenu)
|
||||||
|
|
||||||
function openDeviceGnirehtetMenu(event, args = {}) {
|
function openSystemMenu(event, args = {}) {
|
||||||
const { options = [] } = args
|
const { options = [], channel = 'system-menu-click' } = args
|
||||||
|
|
||||||
const template = options.map((item) => {
|
const template = options.map((item) => {
|
||||||
return {
|
return {
|
||||||
label: item.label,
|
label: item.label,
|
||||||
click() {
|
click() {
|
||||||
controlWindow.webContents.send(item.value)
|
controlWindow.webContents.send(channel, item.value)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -1,24 +0,0 @@
|
|||||||
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
|
||||||
|
|
||||||
export default function (controlWindow) {
|
|
||||||
ipcMain.on('open-device-rotation-menu', openDeviceRotationMenu)
|
|
||||||
|
|
||||||
function openDeviceRotationMenu(event, args = {}) {
|
|
||||||
const { options = [] } = args
|
|
||||||
|
|
||||||
const template = options.map((item) => {
|
|
||||||
return {
|
|
||||||
label: item.label,
|
|
||||||
click: () => {
|
|
||||||
controlWindow.webContents.send(
|
|
||||||
'execute-device-rotation-shell',
|
|
||||||
item.value,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const menu = Menu.buildFromTemplate(template)
|
|
||||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
|
||||||
|
|
||||||
export default function (controlWindow) {
|
|
||||||
ipcMain.on('open-device-volume-menu', openDeviceVolumeMenu)
|
|
||||||
|
|
||||||
function openDeviceVolumeMenu(event, args = {}) {
|
|
||||||
const { options = [] } = args
|
|
||||||
|
|
||||||
const template = options.map((item) => {
|
|
||||||
return {
|
|
||||||
label: item.label,
|
|
||||||
click() {
|
|
||||||
controlWindow.webContents.send('execute-device-volume-shell', item.value)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const menu = Menu.buildFromTemplate(template)
|
|
||||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
import { BrowserWindow, ipcMain } from 'electron'
|
import { BrowserWindow, ipcMain } from 'electron'
|
||||||
import { initControlWindow, openControlWindow } from './helpers/index.js'
|
import { initControlWindow, openControlWindow } from './helpers/index.js'
|
||||||
|
|
||||||
import { devices, gnirehtet, rotation, volume } from './events/index.js'
|
import { menu } from './events/index.js'
|
||||||
|
|
||||||
function onControlMounted(controlWindow) {
|
function onControlMounted(controlWindow) {
|
||||||
ipcMain.on('language-change', (event, data) => {
|
ipcMain.on('language-change', (event, data) => {
|
||||||
@ -12,10 +12,7 @@ function onControlMounted(controlWindow) {
|
|||||||
controlWindow.webContents.send('theme-change', data)
|
controlWindow.webContents.send('theme-change', data)
|
||||||
})
|
})
|
||||||
|
|
||||||
rotation(controlWindow)
|
menu(controlWindow)
|
||||||
devices(controlWindow)
|
|
||||||
volume(controlWindow)
|
|
||||||
gnirehtet(controlWindow)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (mainWindow) => {
|
export default (mainWindow) => {
|
||||||
|
43
electron/exposes/scrcpy/helper.js
Normal file
43
electron/exposes/scrcpy/helper.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Parse scrcpy app list output into structured data
|
||||||
|
* @param {string} rawText - Raw text output from scrcpy --list-apps command
|
||||||
|
* @returns {Array<{
|
||||||
|
* name: string,
|
||||||
|
* packageName: string,
|
||||||
|
* isSystemApp: boolean
|
||||||
|
* }>} Array of parsed app objects
|
||||||
|
*/
|
||||||
|
export function parseScrcpyAppList(rawText) {
|
||||||
|
try {
|
||||||
|
// Split by lines and filter out non-app lines
|
||||||
|
const lines = rawText.split('\n').filter((line) => {
|
||||||
|
const trimmed = line.trim()
|
||||||
|
return trimmed.startsWith('*') || trimmed.startsWith('-')
|
||||||
|
})
|
||||||
|
|
||||||
|
return lines.map((line) => {
|
||||||
|
// Remove leading * or - and trim
|
||||||
|
const cleanLine = line.trim().replace(/^[*\-]\s+/, '')
|
||||||
|
|
||||||
|
// Extract app name and package name using a more precise regex
|
||||||
|
// Matches any characters up to the last [ followed by package name and ]
|
||||||
|
const match = cleanLine.match(/^([^[]+)\[([^\]]+)\]$/)
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, name, packageName] = match
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: name.trim(),
|
||||||
|
packageName: packageName.trim(),
|
||||||
|
isSystemApp: line.trim().startsWith('*'),
|
||||||
|
}
|
||||||
|
}).filter(item => item !== null)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Error parsing scrcpy app list:', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,13 @@ import appStore from '$electron/helpers/store.js'
|
|||||||
import { replaceIP, sleep } from '$renderer/utils/index.js'
|
import { replaceIP, sleep } from '$renderer/utils/index.js'
|
||||||
import commandHelper from '$renderer/utils/command/index.js'
|
import commandHelper from '$renderer/utils/command/index.js'
|
||||||
|
|
||||||
|
import { parseScrcpyAppList } from './helper.js'
|
||||||
|
|
||||||
let adbkit
|
let adbkit
|
||||||
|
|
||||||
const exec = util.promisify(_exec)
|
const exec = util.promisify(_exec)
|
||||||
|
|
||||||
async function shell(command, { stdout, stderr, ...options } = {}) {
|
async function shell(command, { stdout, stderr, signal, ...options } = {}) {
|
||||||
const spawnPath = appStore.get('common.scrcpyPath') || scrcpyPath
|
const spawnPath = appStore.get('common.scrcpyPath') || scrcpyPath
|
||||||
const ADB = appStore.get('common.adbPath') || adbPath
|
const ADB = appStore.get('common.adbPath') || adbPath
|
||||||
const args = command.split(' ')
|
const args = command.split(' ')
|
||||||
@ -21,28 +23,35 @@ async function shell(command, { stdout, stderr, ...options } = {}) {
|
|||||||
...options,
|
...options,
|
||||||
})
|
})
|
||||||
|
|
||||||
scrcpyProcess.stdout.on('data', (data) => {
|
|
||||||
const stringData = data.toString()
|
|
||||||
|
|
||||||
if (stdout) {
|
|
||||||
stdout(stringData, scrcpyProcess)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const stderrList = []
|
const stderrList = []
|
||||||
scrcpyProcess.stderr.on('data', (data) => {
|
|
||||||
const stringData = data.toString()
|
|
||||||
|
|
||||||
stderrList.push(stringData)
|
|
||||||
|
|
||||||
console.error('scrcpyProcess.stderr.data:', stringData)
|
|
||||||
|
|
||||||
if (stderr) {
|
|
||||||
stderr(stringData, scrcpyProcess)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
scrcpyProcess.stdout.on('data', (data) => {
|
||||||
|
const stringData = data.toString()
|
||||||
|
|
||||||
|
if (stdout) {
|
||||||
|
stdout(stringData, scrcpyProcess)
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchList = stringData.match(signal)
|
||||||
|
|
||||||
|
if (matchList) {
|
||||||
|
resolve(matchList, stringData, scrcpyProcess)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
scrcpyProcess.stderr.on('data', (data) => {
|
||||||
|
const stringData = data.toString()
|
||||||
|
|
||||||
|
stderrList.push(stringData)
|
||||||
|
|
||||||
|
console.error('scrcpyProcess.stderr.data:', stringData)
|
||||||
|
|
||||||
|
if (stderr) {
|
||||||
|
stderr(stringData, scrcpyProcess)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
scrcpyProcess.on('close', (code) => {
|
scrcpyProcess.on('close', (code) => {
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
resolve()
|
resolve()
|
||||||
@ -184,6 +193,31 @@ async function helper(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAppList(serial) {
|
||||||
|
const res = await execShell(`--serial="${serial}" --list-apps`)
|
||||||
|
|
||||||
|
const stdout = res.stdout
|
||||||
|
const value = parseScrcpyAppList(stdout)
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startApp(serial, args = {}) {
|
||||||
|
let { commands, packageName, ...options } = args
|
||||||
|
|
||||||
|
commands += ` --new-display --start-app=${packageName}`
|
||||||
|
|
||||||
|
const res = await mirror(serial, { ...options, args: commands, signal: /display id: (\d+)/i })
|
||||||
|
|
||||||
|
const displayId = res?.[1]
|
||||||
|
|
||||||
|
if (!displayId) {
|
||||||
|
throw new Error('The display ID was not obtained.')
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayId
|
||||||
|
}
|
||||||
|
|
||||||
export default (options = {}) => {
|
export default (options = {}) => {
|
||||||
adbkit = options.adbkit
|
adbkit = options.adbkit
|
||||||
|
|
||||||
@ -195,5 +229,7 @@ export default (options = {}) => {
|
|||||||
record,
|
record,
|
||||||
mirrorGroup,
|
mirrorGroup,
|
||||||
helper,
|
helper,
|
||||||
|
getAppList,
|
||||||
|
startApp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<el-dropdown
|
||||||
|
:hide-on-click="false"
|
||||||
|
:disabled="loading || floating"
|
||||||
|
max-height="300px"
|
||||||
|
@command="handleCommand"
|
||||||
|
@mouseenter="getAppData"
|
||||||
|
>
|
||||||
|
<slot :loading :trigger="handleTrigger" />
|
||||||
|
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-for="item of options"
|
||||||
|
:key="item.value"
|
||||||
|
:command="item.value"
|
||||||
|
>
|
||||||
|
{{ $t(item.label) }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
device: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
floating: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
appList: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
options() {
|
||||||
|
const value = this.appList.map(item => ({
|
||||||
|
...item,
|
||||||
|
label: item.name,
|
||||||
|
value: item.packageName,
|
||||||
|
}))
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getAppData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getAppData() {
|
||||||
|
const data = await window.scrcpy.getAppList(this.device.id)
|
||||||
|
|
||||||
|
this.appList = data || []
|
||||||
|
},
|
||||||
|
handleTrigger() {
|
||||||
|
if (!this.floating) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const channel = 'startApp'
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.once(
|
||||||
|
channel,
|
||||||
|
(event, data) => {
|
||||||
|
this.handleCommand(data)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const options = toRaw(this.options)
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.send('open-system-menu', {
|
||||||
|
channel,
|
||||||
|
options,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async handleCommand(value) {
|
||||||
|
this.loading = true
|
||||||
|
|
||||||
|
const title = this.$store.device.getLabel(this.device, 'mirror')
|
||||||
|
|
||||||
|
const commands = this.$store.preference.scrcpyParameter(this.device.id, {
|
||||||
|
excludes: ['--otg', '--mouse=aoa', '--keyboard=aoa'],
|
||||||
|
})
|
||||||
|
|
||||||
|
await window.scrcpy.startApp(this.device.id, { title, commands, packageName: value })
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
@ -55,8 +55,10 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const channel = 'stop-device-gnirehtet'
|
||||||
|
|
||||||
window.electron.ipcRenderer.once(
|
window.electron.ipcRenderer.once(
|
||||||
'stop-device-gnirehtet',
|
channel,
|
||||||
(event, data) => {
|
(event, data) => {
|
||||||
this.handleStop()
|
this.handleStop()
|
||||||
},
|
},
|
||||||
@ -65,11 +67,11 @@ export default {
|
|||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
label: window.t('device.control.gnirehtet.stop'),
|
label: window.t('device.control.gnirehtet.stop'),
|
||||||
value: 'stop-device-gnirehtet',
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
window.electron.ipcRenderer.send('open-device-gnirehtet-menu', {
|
window.electron.ipcRenderer.send('open-system-menu', {
|
||||||
|
channel,
|
||||||
options,
|
options,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -73,8 +73,10 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const channel = 'rotationScreen'
|
||||||
|
|
||||||
window.electron.ipcRenderer.once(
|
window.electron.ipcRenderer.once(
|
||||||
'execute-device-rotation-shell',
|
channel,
|
||||||
(event, data) => {
|
(event, data) => {
|
||||||
this.handleCommand(data)
|
this.handleCommand(data)
|
||||||
},
|
},
|
||||||
@ -82,7 +84,8 @@ export default {
|
|||||||
|
|
||||||
const options = toRaw(this.options)
|
const options = toRaw(this.options)
|
||||||
|
|
||||||
window.electron.ipcRenderer.send('open-device-rotation-menu', {
|
window.electron.ipcRenderer.send('open-system-menu', {
|
||||||
|
channel,
|
||||||
options,
|
options,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -97,6 +100,8 @@ export default {
|
|||||||
await sleep(500)
|
await sleep(500)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('command', command)
|
||||||
|
|
||||||
this.$adb.deviceShell(this.device.id, command)
|
this.$adb.deviceShell(this.device.id, command)
|
||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
@ -67,16 +67,20 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const channel = 'changeVolume'
|
||||||
|
|
||||||
window.electron.ipcRenderer.once(
|
window.electron.ipcRenderer.once(
|
||||||
'execute-device-volume-shell',
|
channel,
|
||||||
(event, data) => {
|
(event, data) => {
|
||||||
|
console.log('data')
|
||||||
this.handleCommand(data)
|
this.handleCommand(data)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const options = toRaw(this.options)
|
const options = toRaw(this.options)
|
||||||
|
|
||||||
window.electron.ipcRenderer.send('open-device-volume-menu', {
|
window.electron.ipcRenderer.send('open-system-menu', {
|
||||||
|
channel,
|
||||||
options,
|
options,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -64,10 +64,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// import Synergy from './Synergy/index.vue'
|
||||||
import Application from './Application/index.vue'
|
import Application from './Application/index.vue'
|
||||||
|
import ApplicationStart from './ApplicationStart/index.vue'
|
||||||
import FileManage from './FileManage/index.vue'
|
import FileManage from './FileManage/index.vue'
|
||||||
import Gnirehtet from './Gnirehtet/index.vue'
|
import Gnirehtet from './Gnirehtet/index.vue'
|
||||||
import Synergy from './Synergy/index.vue'
|
|
||||||
import Rotation from './Rotation/index.vue'
|
import Rotation from './Rotation/index.vue'
|
||||||
import Screenshot from './Screenshot/index.vue'
|
import Screenshot from './Screenshot/index.vue'
|
||||||
import Shell from './Shell/index.vue'
|
import Shell from './Shell/index.vue'
|
||||||
@ -76,10 +77,11 @@ import Volume from './Volume/index.vue'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
// Synergy,
|
||||||
Screenshot,
|
Screenshot,
|
||||||
Application,
|
Application,
|
||||||
|
ApplicationStart,
|
||||||
Gnirehtet,
|
Gnirehtet,
|
||||||
Synergy,
|
|
||||||
Rotation,
|
Rotation,
|
||||||
Volume,
|
Volume,
|
||||||
FileManage,
|
FileManage,
|
||||||
@ -125,6 +127,11 @@ export default {
|
|||||||
window.scrcpy.helper(this.device.id, '--turn-screen-off')
|
window.scrcpy.helper(this.device.id, '--turn-screen-off')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'device.control.startApp',
|
||||||
|
elIcon: 'Files',
|
||||||
|
component: 'ApplicationStart',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'device.control.notification',
|
label: 'device.control.notification',
|
||||||
elIcon: 'Notification',
|
elIcon: 'Notification',
|
||||||
@ -187,14 +194,14 @@ export default {
|
|||||||
component: 'Gnirehtet',
|
component: 'Gnirehtet',
|
||||||
tips: 'device.control.gnirehtet.tips',
|
tips: 'device.control.gnirehtet.tips',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: 'device.control.mirror-group.name',
|
// label: 'device.control.mirror-group.name',
|
||||||
svgIcon: 'multi-screen',
|
// svgIcon: 'multi-screen',
|
||||||
iconClass: '',
|
// iconClass: '',
|
||||||
component: 'Synergy',
|
// component: 'Synergy',
|
||||||
tips: 'device.control.mirror-group.tips',
|
// tips: 'device.control.mirror-group.tips',
|
||||||
hiddenKeys: ['floating'],
|
// hiddenKeys: ['floating'],
|
||||||
},
|
// },
|
||||||
]
|
]
|
||||||
|
|
||||||
const handler = item =>
|
const handler = item =>
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
"device.control.reboot": "Reboot",
|
"device.control.reboot": "Reboot",
|
||||||
"device.control.turnScreenOff": "Turn screen off",
|
"device.control.turnScreenOff": "Turn screen off",
|
||||||
"device.control.turnScreenOff.tips": "Turn off the screen while maintaining control (Experimental): This action will create an EscrcpyHelper process; manually closing this process will reopen the screen.",
|
"device.control.turnScreenOff.tips": "Turn off the screen while maintaining control (Experimental): This action will create an EscrcpyHelper process; manually closing this process will reopen the screen.",
|
||||||
|
"device.control.startApp": "Start APP",
|
||||||
"device.control.power": "Power",
|
"device.control.power": "Power",
|
||||||
"device.control.power.tips": "Turn screen on/off",
|
"device.control.power.tips": "Turn screen on/off",
|
||||||
"device.control.notification": "Notification",
|
"device.control.notification": "Notification",
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
"device.control.reboot": "Перезагрузить",
|
"device.control.reboot": "Перезагрузить",
|
||||||
"device.control.turnScreenOff": "Выключить экран",
|
"device.control.turnScreenOff": "Выключить экран",
|
||||||
"device.control.turnScreenOff.tips": "Отключение экрана с сохранением контроля (экспериментально): это действие создаст процесс EscrcpyHelper; при ручном завершении этого процесса экран снова включится.",
|
"device.control.turnScreenOff.tips": "Отключение экрана с сохранением контроля (экспериментально): это действие создаст процесс EscrcpyHelper; при ручном завершении этого процесса экран снова включится.",
|
||||||
|
"device.control.startApp": "Start APP",
|
||||||
"device.control.power": "Питание",
|
"device.control.power": "Питание",
|
||||||
"device.control.power.tips": "Включить/выключить экран",
|
"device.control.power.tips": "Включить/выключить экран",
|
||||||
"device.control.notification": "Уведомление",
|
"device.control.notification": "Уведомление",
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
"device.control.reboot": "重启设备",
|
"device.control.reboot": "重启设备",
|
||||||
"device.control.turnScreenOff": "关闭屏幕",
|
"device.control.turnScreenOff": "关闭屏幕",
|
||||||
"device.control.turnScreenOff.tips": "关闭屏幕且保持控制(实验功能):此操作将创建一个 EscrcpyHelper 进程,手动关闭进程将重新打开屏幕。",
|
"device.control.turnScreenOff.tips": "关闭屏幕且保持控制(实验功能):此操作将创建一个 EscrcpyHelper 进程,手动关闭进程将重新打开屏幕。",
|
||||||
|
"device.control.startApp": "启动应用",
|
||||||
"device.control.power": "电源键",
|
"device.control.power": "电源键",
|
||||||
"device.control.power.tips": "可以用来开启或关闭屏幕",
|
"device.control.power.tips": "可以用来开启或关闭屏幕",
|
||||||
"device.control.notification": "通知栏",
|
"device.control.notification": "通知栏",
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
"device.control.reboot": "重啟裝置",
|
"device.control.reboot": "重啟裝置",
|
||||||
"device.control.turnScreenOff": "關閉螢幕",
|
"device.control.turnScreenOff": "關閉螢幕",
|
||||||
"device.control.turnScreenOff.tips": "關閉螢幕且保持控制(實驗功能):此操作將創建一個 EscrcpyHelper 進程,手動關閉該進程將重新打開螢幕。",
|
"device.control.turnScreenOff.tips": "關閉螢幕且保持控制(實驗功能):此操作將創建一個 EscrcpyHelper 進程,手動關閉該進程將重新打開螢幕。",
|
||||||
|
"device.control.startApp": "Start APP",
|
||||||
"device.control.power": "電源鍵",
|
"device.control.power": "電源鍵",
|
||||||
"device.control.power.tips": "可以用來開啟或關閉螢幕",
|
"device.control.power.tips": "可以用來開啟或關閉螢幕",
|
||||||
"device.control.notification": "通知欄",
|
"device.control.notification": "通知欄",
|
||||||
|
@ -26,7 +26,7 @@ export const useDeviceStore = defineStore({
|
|||||||
return this.config
|
return this.config
|
||||||
},
|
},
|
||||||
getLabel(device, params) {
|
getLabel(device, params) {
|
||||||
if (!device) {
|
if (!device.id) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export const useDeviceStore = defineStore({
|
|||||||
|
|
||||||
const appName = capitalize(packageName)
|
const appName = capitalize(packageName)
|
||||||
|
|
||||||
const deviceName = `${data.$remark || data.$name}${data.$wifi ? '(WIFI)' : ''}`
|
const deviceName = `${data?.$remark || data.$name}${data.$wifi ? '(WIFI)' : ''}`
|
||||||
|
|
||||||
const currentTime = dayjs().format('YYYYMMDDHHmmss')
|
const currentTime = dayjs().format('YYYYMMDDHHmmss')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user