mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-27 17:00:53 +01:00
feat: ✨ Support floating control bar
This commit is contained in:
parent
47ae53d623
commit
8807e50413
118
control/App.vue
Normal file
118
control/App.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<el-config-provider :locale="locale">
|
||||||
|
<div
|
||||||
|
class="flex items-center bg-primary-100 dark:bg-gray-800 absolute inset-0 h-full"
|
||||||
|
>
|
||||||
|
<div class="flex-none h-full">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="!px-3 bg-transparent !border-none !h-full"
|
||||||
|
plain
|
||||||
|
@click="handleClose"
|
||||||
|
>
|
||||||
|
<el-icon class="">
|
||||||
|
<ElIconCircleCloseFilled />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="h-4 w-px mx-1 bg-primary-200 dark:bg-primary-800 flex-none"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div class="flex-none h-full">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
class="!px-2 !h-full"
|
||||||
|
icon="Switch"
|
||||||
|
@click="switchDevice"
|
||||||
|
>
|
||||||
|
<span class="mr-2">{{ deviceInfo.$remark || deviceInfo.$name }}</span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="h-4 w-px mx-1 bg-primary-200 dark:bg-primary-800 flex-none"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div class="flex-1 w-0 overflow-hidden h-full">
|
||||||
|
<ControlBar class="!h-full" :device="deviceInfo" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="h-4 w-px mx-1 bg-primary-200 dark:bg-primary-800 flex-none"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div class="flex-none h-full app-region-drag">
|
||||||
|
<el-button type="primary" text class="!px-3 !h-full">
|
||||||
|
<el-icon class="">
|
||||||
|
<ElIconRank />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import ControlBar from '$/components/Device/components/ControlBar/index.vue'
|
||||||
|
|
||||||
|
import { i18n } from '$/locales/index.js'
|
||||||
|
|
||||||
|
import localeModel from '$/plugins/element-plus/locale.js'
|
||||||
|
|
||||||
|
import { useDeviceStore, useThemeStore } from '$/store/index.js'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const themeStore = useThemeStore()
|
||||||
|
const deviceStore = useDeviceStore()
|
||||||
|
|
||||||
|
themeStore.init()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.electron.ipcRenderer.send('control-mounted')
|
||||||
|
})
|
||||||
|
|
||||||
|
const locale = computed(() => {
|
||||||
|
const i18nLocale = i18n.global.locale.value
|
||||||
|
|
||||||
|
const value = localeModel[i18nLocale]
|
||||||
|
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
|
||||||
|
const deviceInfo = ref({})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('device-change', (event, data) => {
|
||||||
|
deviceInfo.value = data
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('language-change', (event, data) => {
|
||||||
|
i18n.global.locale.value = data
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('theme-change', (event, data) => {
|
||||||
|
themeStore.update(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
window.electron.ipcRenderer.send('hide-active-window')
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceList = ref([])
|
||||||
|
|
||||||
|
async function switchDevice(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const data = await deviceStore.getList()
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.send('show-device-list', data)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.app-region-drag {
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
||||||
|
</style>
|
44
control/electron/helpers/index.js
Normal file
44
control/electron/helpers/index.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { BrowserWindow } from 'electron'
|
||||||
|
import { getLogoPath } from '$electron/configs/index.js'
|
||||||
|
import { sleep } from '$renderer/utils/index.js'
|
||||||
|
import { loadPage } from '$electron/helpers/index.js'
|
||||||
|
|
||||||
|
export function initControlWindow(mainWindow) {
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
const controlWindow = new BrowserWindow({
|
||||||
|
icon: getLogoPath(),
|
||||||
|
width: 500,
|
||||||
|
minWidth: 500,
|
||||||
|
height: 30,
|
||||||
|
maxHeight: 30,
|
||||||
|
frame: false,
|
||||||
|
show: false,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
skipTaskbar: true,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.mjs'),
|
||||||
|
nodeIntegration: true,
|
||||||
|
sandbox: false,
|
||||||
|
spellcheck: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
controlWindow.customId = 'control'
|
||||||
|
|
||||||
|
loadPage(controlWindow, 'control/')
|
||||||
|
|
||||||
|
return controlWindow
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openControlWindow(win, data, args = {}) {
|
||||||
|
if (args.sleep) {
|
||||||
|
await sleep(args.sleep)
|
||||||
|
}
|
||||||
|
|
||||||
|
win.show()
|
||||||
|
win.webContents.send('device-change', data)
|
||||||
|
}
|
56
control/electron/main.js
Normal file
56
control/electron/main.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { BrowserWindow, ipcMain, Menu } from 'electron'
|
||||||
|
import { initControlWindow, openControlWindow } from './helpers/index.js'
|
||||||
|
|
||||||
|
export default (mainWindow) => {
|
||||||
|
let controlWindow
|
||||||
|
|
||||||
|
ipcMain.on('open-control-window', (event, data) => {
|
||||||
|
controlWindow = BrowserWindow.getAllWindows().find(
|
||||||
|
win => win.customId === 'control',
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!controlWindow) {
|
||||||
|
controlWindow = initControlWindow(mainWindow)
|
||||||
|
|
||||||
|
ipcMain.on('control-mounted', () => {
|
||||||
|
openControlWindow(controlWindow, data)
|
||||||
|
})
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
openControlWindow(controlWindow, data)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('language-change', (event, data) => {
|
||||||
|
if (controlWindow) {
|
||||||
|
controlWindow.webContents.send('language-change', data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('theme-change', (event, data) => {
|
||||||
|
if (controlWindow) {
|
||||||
|
controlWindow.webContents.send('theme-change', data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('show-device-list', (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))
|
||||||
|
})
|
||||||
|
}
|
13
control/index.html
Normal file
13
control/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/logo.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Escrcpy Control</title>
|
||||||
|
</head>
|
||||||
|
<body class="overflow-hidden">
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="./index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
5
control/index.js
Normal file
5
control/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import bootstrap from '../src/bootstrap/index.js'
|
||||||
|
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
bootstrap(App)
|
@ -22,3 +22,16 @@ export const trayPath
|
|||||||
: extraResolve('common/tray/icon.png')
|
: extraResolve('common/tray/icon.png')
|
||||||
|
|
||||||
export const logPath = process.env.LOG_PATH
|
export const logPath = process.env.LOG_PATH
|
||||||
|
|
||||||
|
export function getLogoPath() {
|
||||||
|
let icon = logoPath
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
icon = icoLogoPath
|
||||||
|
}
|
||||||
|
else if (process.platform === 'darwin') {
|
||||||
|
icon = icnsLogoPath
|
||||||
|
}
|
||||||
|
|
||||||
|
return logoPath
|
||||||
|
}
|
||||||
|
19
electron/events/app/index.js
Normal file
19
electron/events/app/index.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { app, BrowserWindow, ipcMain } from 'electron'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
ipcMain.on('restart-app', () => {
|
||||||
|
app.isQuiting = true
|
||||||
|
app.relaunch()
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('close-active-window', (event) => {
|
||||||
|
const win = BrowserWindow.getFocusedWindow()
|
||||||
|
win.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('hide-active-window', (event) => {
|
||||||
|
const win = BrowserWindow.getFocusedWindow()
|
||||||
|
win.hide()
|
||||||
|
})
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import { app, ipcMain } from 'electron'
|
import appEvents from './app/index.js'
|
||||||
|
|
||||||
import handles from './handles/index.js'
|
import handles from './handles/index.js'
|
||||||
import shortcuts from './shortcuts/index.js'
|
import shortcuts from './shortcuts/index.js'
|
||||||
import theme from './theme/index.js'
|
import theme from './theme/index.js'
|
||||||
@ -7,12 +6,7 @@ import tray from './tray/index.js'
|
|||||||
import updater from './updater/index.js'
|
import updater from './updater/index.js'
|
||||||
|
|
||||||
export default (mainWindow) => {
|
export default (mainWindow) => {
|
||||||
ipcMain.on('restart-app', () => {
|
appEvents(mainWindow)
|
||||||
app.isQuiting = true
|
|
||||||
app.relaunch()
|
|
||||||
app.quit()
|
|
||||||
})
|
|
||||||
|
|
||||||
handles(mainWindow)
|
handles(mainWindow)
|
||||||
updater(mainWindow)
|
updater(mainWindow)
|
||||||
tray(mainWindow)
|
tray(mainWindow)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { resolve } from 'node:path'
|
import { join, resolve } from 'node:path'
|
||||||
import { contextBridge } from 'electron'
|
import { contextBridge } from 'electron'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
@ -56,3 +56,15 @@ export async function executeI18n(mainWindow, value) {
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function loadPage(win, prefix = '') {
|
||||||
|
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin - Vite@2.x
|
||||||
|
const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
|
||||||
|
|
||||||
|
if (VITE_DEV_SERVER_URL) {
|
||||||
|
win.loadURL(join(VITE_DEV_SERVER_URL, prefix))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
win.loadFile(join(process.env.DIST, prefix, 'index.html'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ if (isEqual(appStore.store, {})) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
...appStore,
|
||||||
...createProxy(appStore, [
|
...createProxy(appStore, [
|
||||||
'set',
|
'set',
|
||||||
'get',
|
'get',
|
||||||
@ -21,7 +22,6 @@ export default {
|
|||||||
'onDidAnyChange',
|
'onDidAnyChange',
|
||||||
'openInEditor',
|
'openInEditor',
|
||||||
]),
|
]),
|
||||||
...appStore,
|
|
||||||
getAll: () => appStore.store,
|
getAll: () => appStore.store,
|
||||||
setAll: value => (appStore.store = value),
|
setAll: value => (appStore.store = value),
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,14 @@ import log from './helpers/log.js'
|
|||||||
import './helpers/console.js'
|
import './helpers/console.js'
|
||||||
import appStore from './helpers/store.js'
|
import appStore from './helpers/store.js'
|
||||||
|
|
||||||
import { icnsLogoPath, icoLogoPath, logoPath } from './configs/index.js'
|
import { getLogoPath } from './configs/index.js'
|
||||||
|
|
||||||
import events from './events/index.js'
|
import events from './events/index.js'
|
||||||
|
|
||||||
|
import control from '$control/electron/main.js'
|
||||||
|
|
||||||
|
import { loadPage } from './helpers/index.js'
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
@ -51,25 +55,10 @@ contextMenu({
|
|||||||
process.env.DIST = path.join(__dirname, '../dist')
|
process.env.DIST = path.join(__dirname, '../dist')
|
||||||
|
|
||||||
let mainWindow
|
let mainWindow
|
||||||
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin - Vite@2.x
|
|
||||||
const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
|
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
let icon = logoPath
|
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
icon = icoLogoPath
|
|
||||||
} else if (process.platform === 'darwin') {
|
|
||||||
icon = icnsLogoPath
|
|
||||||
}
|
|
||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
// 这里设置的图标仅在开发模式生效,打包后将使用应用程序图标
|
icon: getLogoPath(),
|
||||||
...(!isPackaged
|
|
||||||
? {
|
|
||||||
icon,
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
show: false,
|
show: false,
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 800,
|
height: 800,
|
||||||
@ -96,13 +85,11 @@ function createWindow() {
|
|||||||
return { action: 'deny' }
|
return { action: 'deny' }
|
||||||
})
|
})
|
||||||
|
|
||||||
if (VITE_DEV_SERVER_URL) {
|
loadPage(mainWindow)
|
||||||
mainWindow.loadURL(VITE_DEV_SERVER_URL)
|
|
||||||
} else {
|
|
||||||
mainWindow.loadFile(path.join(process.env.DIST, 'index.html'))
|
|
||||||
}
|
|
||||||
|
|
||||||
events(mainWindow)
|
events(mainWindow)
|
||||||
|
|
||||||
|
control(mainWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
|
@ -63,6 +63,7 @@ export default antfu(
|
|||||||
'unicorn/consistent-function-scoping': 'off',
|
'unicorn/consistent-function-scoping': 'off',
|
||||||
'regexp/no-unused-capturing-group': 'off',
|
'regexp/no-unused-capturing-group': 'off',
|
||||||
'regexp/no-dupe-disjunctions': 'off',
|
'regexp/no-dupe-disjunctions': 'off',
|
||||||
|
'perfectionist/sort-imports': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
"$/*": ["src/*"],
|
"$/*": ["src/*"],
|
||||||
"$root/*": ["*"],
|
"$root/*": ["*"],
|
||||||
"$electron/*": ["electron/*"],
|
"$electron/*": ["electron/*"],
|
||||||
"$renderer/*": ["src/*"]
|
"$renderer/*": ["src/*"],
|
||||||
|
"$control/*": ["control/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist", "dist-electron", "dist-release"],
|
"exclude": ["node_modules", "dist", "dist-electron", "dist-release"],
|
||||||
|
48
src/bootstrap/default/index.js
Normal file
48
src/bootstrap/default/index.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { createApp, toRaw } from 'vue'
|
||||||
|
|
||||||
|
import icons from '$/icons/index.js'
|
||||||
|
|
||||||
|
import { i18n, t } from '$/locales/index.js'
|
||||||
|
|
||||||
|
import plugins from '$/plugins/index.js'
|
||||||
|
|
||||||
|
import store from '$/store/index.js'
|
||||||
|
|
||||||
|
import { replaceIP, restoreIP } from '$/utils/index.js'
|
||||||
|
|
||||||
|
import '$/utils/console.js'
|
||||||
|
|
||||||
|
import 'virtual:uno.css'
|
||||||
|
import '$/styles/index.js'
|
||||||
|
|
||||||
|
export default (App) => {
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
app.use(store)
|
||||||
|
|
||||||
|
app.use(plugins)
|
||||||
|
|
||||||
|
app.use(icons)
|
||||||
|
|
||||||
|
app.use(i18n)
|
||||||
|
window.t = t
|
||||||
|
|
||||||
|
app.config.globalProperties.$path = window.nodePath
|
||||||
|
app.config.globalProperties.$appStore = window.appStore
|
||||||
|
app.config.globalProperties.$appLog = window.appLog
|
||||||
|
app.config.globalProperties.$electron = window.electron
|
||||||
|
|
||||||
|
app.config.globalProperties.$adb = window.adbkit
|
||||||
|
app.config.globalProperties.$scrcpy = window.scrcpy
|
||||||
|
app.config.globalProperties.$gnirehtet = window.gnirehtet
|
||||||
|
|
||||||
|
app.config.globalProperties.$replaceIP = replaceIP
|
||||||
|
app.config.globalProperties.$restoreIP = restoreIP
|
||||||
|
|
||||||
|
app.config.globalProperties.$toRaw = toRaw
|
||||||
|
|
||||||
|
app.mount('#app').$nextTick(() => {
|
||||||
|
// Remove Preload scripts loading
|
||||||
|
postMessage({ payload: 'removeLoading' }, '*')
|
||||||
|
})
|
||||||
|
}
|
3
src/bootstrap/index.js
Normal file
3
src/bootstrap/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import bootstrap from './default/index.js'
|
||||||
|
|
||||||
|
export default bootstrap
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="bg-primary-100 dark:bg-gray-800 flex items-center group -my-[8px] h-9 overflow-hidden"
|
class="bg-primary-100 dark:bg-gray-800 flex items-center group h-9 overflow-hidden"
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { sleep } from '$/utils'
|
import { sleep } from '$/utils'
|
||||||
|
import { openFloatControl } from '$/utils/device/index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -52,6 +53,8 @@ export default {
|
|||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
openFloatControl(toRaw(this.row))
|
||||||
|
|
||||||
await mirroring
|
await mirroring
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@ -63,6 +66,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onStdout() {},
|
onStdout() {},
|
||||||
onStderr() {},
|
onStderr() {},
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { sleep } from '$/utils'
|
import { sleep } from '$/utils'
|
||||||
|
import { openFloatControl } from '$/utils/device/index.js'
|
||||||
|
|
||||||
import DeployDialog from './components/DeployDialog/index.vue'
|
import DeployDialog from './components/DeployDialog/index.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -58,6 +60,8 @@ export default {
|
|||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
openFloatControl(toRaw(this.row))
|
||||||
|
|
||||||
await mirroring
|
await mirroring
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@ -69,6 +73,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onStdout() {},
|
onStdout() {},
|
||||||
onStderr() {},
|
onStderr() {},
|
||||||
},
|
},
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { sleep } from '$/utils'
|
import { sleep } from '$/utils'
|
||||||
|
import { openFloatControl } from '$/utils/device/index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -49,6 +50,8 @@ export default {
|
|||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
openFloatControl(toRaw(this.row))
|
||||||
|
|
||||||
await recording
|
await recording
|
||||||
|
|
||||||
await this.handleSuccess(savePath)
|
await this.handleSuccess(savePath)
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<ControlBar :device="row" />
|
<ControlBar :device="row" class="-my-[8px]" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
@ -50,6 +50,7 @@ export default {
|
|||||||
set(value) {
|
set(value) {
|
||||||
this.locale = value
|
this.locale = value
|
||||||
this.$emit('update:model-value', value)
|
this.$emit('update:model-value', value)
|
||||||
|
window.electron.ipcRenderer.send('language-change', value)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -74,6 +74,7 @@ export default {
|
|||||||
'preferenceData.theme': {
|
'preferenceData.theme': {
|
||||||
handler(value) {
|
handler(value) {
|
||||||
this.$store.theme.update(value)
|
this.$store.theme.update(value)
|
||||||
|
window.electron.ipcRenderer.send('theme-change', value)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'preferenceData.adbPath': {
|
'preferenceData.adbPath': {
|
||||||
|
@ -237,6 +237,8 @@
|
|||||||
"preferences.common.gnirehtet.fix.name": "Gnirehtet Fix",
|
"preferences.common.gnirehtet.fix.name": "Gnirehtet Fix",
|
||||||
"preferences.common.gnirehtet.fix.placeholder": "Turning this on will try to fix reverse tethering issues on some devices",
|
"preferences.common.gnirehtet.fix.placeholder": "Turning this on will try to fix reverse tethering issues on some devices",
|
||||||
"preferences.common.gnirehtet.fix.tips": "Note: May cause duplicate gnirehtet client installations",
|
"preferences.common.gnirehtet.fix.tips": "Note: May cause duplicate gnirehtet client installations",
|
||||||
|
"preferences.common.floatControl.name": "Floating Control Bar",
|
||||||
|
"preferences.common.floatControl.placeholder": "Once enabled, the device floating control bar will automatically open during mirroring",
|
||||||
"preferences.common.auto-connect.name": "Auto Connect",
|
"preferences.common.auto-connect.name": "Auto Connect",
|
||||||
"preferences.common.auto-connect.placeholder": "When enabled, the software will attempt to automatically connect to historical devices upon startup.",
|
"preferences.common.auto-connect.placeholder": "When enabled, the software will attempt to automatically connect to historical devices upon startup.",
|
||||||
"preferences.common.auto-mirror.name": "Auto Mirror",
|
"preferences.common.auto-mirror.name": "Auto Mirror",
|
||||||
|
@ -237,6 +237,8 @@
|
|||||||
"preferences.common.gnirehtet.fix.name": "gnirehtet 修复",
|
"preferences.common.gnirehtet.fix.name": "gnirehtet 修复",
|
||||||
"preferences.common.gnirehtet.fix.placeholder": "开启将尝试修复某些机型二次开启反向供网功能失败的问题",
|
"preferences.common.gnirehtet.fix.placeholder": "开启将尝试修复某些机型二次开启反向供网功能失败的问题",
|
||||||
"preferences.common.gnirehtet.fix.tips": "注意:可能导致 gnirehtet 客户端重复安装",
|
"preferences.common.gnirehtet.fix.tips": "注意:可能导致 gnirehtet 客户端重复安装",
|
||||||
|
"preferences.common.floatControl.name": "浮动操控栏",
|
||||||
|
"preferences.common.floatControl.placeholder": "启用后,镜像时将会自动打开设备浮动操控栏",
|
||||||
"preferences.common.auto-connect.name": "自动连接设备",
|
"preferences.common.auto-connect.name": "自动连接设备",
|
||||||
"preferences.common.auto-connect.placeholder": "启用后,该软件将在启动时尝试自动连接到历史无线设备",
|
"preferences.common.auto-connect.placeholder": "启用后,该软件将在启动时尝试自动连接到历史无线设备",
|
||||||
"preferences.common.auto-mirror.name": "自动执行镜像",
|
"preferences.common.auto-mirror.name": "自动执行镜像",
|
||||||
|
@ -237,6 +237,8 @@
|
|||||||
"preferences.common.gnirehtet.fix.name": "gnirehtet 修復",
|
"preferences.common.gnirehtet.fix.name": "gnirehtet 修復",
|
||||||
"preferences.common.gnirehtet.fix.placeholder": "開啟將嘗試修復某些機型二次開啟反向網路分享功能失敗的問題",
|
"preferences.common.gnirehtet.fix.placeholder": "開啟將嘗試修復某些機型二次開啟反向網路分享功能失敗的問題",
|
||||||
"preferences.common.gnirehtet.fix.tips": "注意:可能導致 gnirehtet 客戶端重複安裝",
|
"preferences.common.gnirehtet.fix.tips": "注意:可能導致 gnirehtet 客戶端重複安裝",
|
||||||
|
"preferences.common.floatControl.name": "浮動操控欄",
|
||||||
|
"preferences.common.floatControl.placeholder": "啟用後,鏡像時將會自動開啟設備浮動操控欄",
|
||||||
"preferences.common.auto-connect.name": "自動連接裝置",
|
"preferences.common.auto-connect.name": "自動連接裝置",
|
||||||
"preferences.common.auto-connect.placeholder": "啟用後,該軟體將在啟動時嘗試自動連接到歷史無線裝置",
|
"preferences.common.auto-connect.placeholder": "啟用後,該軟體將在啟動時嘗試自動連接到歷史無線裝置",
|
||||||
"preferences.common.auto-mirror.name": "自動執行鏡像",
|
"preferences.common.auto-mirror.name": "自動執行鏡像",
|
||||||
|
45
src/main.js
45
src/main.js
@ -1,46 +1,5 @@
|
|||||||
import { replaceIP, restoreIP } from '$/utils/index.js'
|
import bootstrap from './bootstrap/index.js'
|
||||||
|
|
||||||
import { createApp, toRaw } from 'vue'
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
|
||||||
import icons from './icons/index.js'
|
bootstrap(App)
|
||||||
|
|
||||||
import { i18n, t } from './locales/index.js'
|
|
||||||
import plugins from './plugins/index.js'
|
|
||||||
|
|
||||||
import store from './store/index.js'
|
|
||||||
|
|
||||||
import '$/utils/console.js'
|
|
||||||
|
|
||||||
import 'virtual:uno.css'
|
|
||||||
import './styles/index.js'
|
|
||||||
|
|
||||||
const app = createApp(App)
|
|
||||||
|
|
||||||
app.use(store)
|
|
||||||
|
|
||||||
app.use(plugins)
|
|
||||||
|
|
||||||
app.use(icons)
|
|
||||||
|
|
||||||
app.use(i18n)
|
|
||||||
window.t = t
|
|
||||||
|
|
||||||
app.config.globalProperties.$path = window.nodePath
|
|
||||||
app.config.globalProperties.$appStore = window.appStore
|
|
||||||
app.config.globalProperties.$appLog = window.appLog
|
|
||||||
app.config.globalProperties.$electron = window.electron
|
|
||||||
|
|
||||||
app.config.globalProperties.$adb = window.adbkit
|
|
||||||
app.config.globalProperties.$scrcpy = window.scrcpy
|
|
||||||
app.config.globalProperties.$gnirehtet = window.gnirehtet
|
|
||||||
|
|
||||||
app.config.globalProperties.$replaceIP = replaceIP
|
|
||||||
app.config.globalProperties.$restoreIP = restoreIP
|
|
||||||
|
|
||||||
app.config.globalProperties.$toRaw = toRaw
|
|
||||||
|
|
||||||
app.mount('#app').$nextTick(() => {
|
|
||||||
// Remove Preload scripts loading
|
|
||||||
postMessage({ payload: 'removeLoading' }, '*')
|
|
||||||
})
|
|
||||||
|
@ -129,6 +129,13 @@ export default {
|
|||||||
placeholder: 'preferences.common.gnirehtet.fix.placeholder',
|
placeholder: 'preferences.common.gnirehtet.fix.placeholder',
|
||||||
tips: 'preferences.common.gnirehtet.fix.tips',
|
tips: 'preferences.common.gnirehtet.fix.tips',
|
||||||
},
|
},
|
||||||
|
floatControl: {
|
||||||
|
label: 'preferences.common.floatControl.name',
|
||||||
|
field: 'floatControl',
|
||||||
|
type: 'Switch',
|
||||||
|
value: undefined,
|
||||||
|
placeholder: 'preferences.common.floatControl.placeholder',
|
||||||
|
},
|
||||||
debug: {
|
debug: {
|
||||||
label: 'preferences.common.debug.name',
|
label: 'preferences.common.debug.name',
|
||||||
field: 'debug',
|
field: 'debug',
|
||||||
|
@ -72,3 +72,13 @@ export async function selectAndSendFileToDevice(
|
|||||||
|
|
||||||
return successFiles
|
return successFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function openFloatControl(deviceInfo) {
|
||||||
|
const floatControl = window.appStore.get('common.floatControl')
|
||||||
|
|
||||||
|
if (!floatControl) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.send('open-control-window', deviceInfo)
|
||||||
|
}
|
||||||
|
@ -13,37 +13,37 @@ import postcssConfig from './postcss.config.js'
|
|||||||
|
|
||||||
import useAutoImports from './src/plugins/auto.js'
|
import useAutoImports from './src/plugins/auto.js'
|
||||||
|
|
||||||
const merge = (config, { command = '' } = {}) =>
|
const alias = {
|
||||||
mergeConfig(
|
$: resolve('src'),
|
||||||
|
$root: resolve(),
|
||||||
|
$renderer: resolve('src'),
|
||||||
|
$electron: resolve('electron'),
|
||||||
|
$control: resolve('control'),
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeCommon(config, { command = '' } = {}) {
|
||||||
|
return mergeConfig(
|
||||||
{
|
{
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias,
|
||||||
$root: resolve(),
|
|
||||||
$electron: resolve('electron'),
|
|
||||||
$renderer: resolve('src'),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
plugins: [...(command === 'serve' ? [notBundle()] : [])],
|
plugins: [...(command === 'serve' ? [notBundle()] : [])],
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default args =>
|
export default function (args) {
|
||||||
merge(
|
return mergeCommon(
|
||||||
defineConfig({
|
defineConfig({
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: {
|
input: {
|
||||||
main: resolve('index.html'),
|
main: resolve('index.html'),
|
||||||
|
control: resolve('control/index.html'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
$: resolve('src'),
|
|
||||||
$electron: resolve('electron'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: [
|
plugins: [
|
||||||
useUnoCSS(),
|
useUnoCSS(),
|
||||||
useSvg(),
|
useSvg(),
|
||||||
@ -54,11 +54,11 @@ export default args =>
|
|||||||
useElectron({
|
useElectron({
|
||||||
main: {
|
main: {
|
||||||
entry: 'electron/main.js',
|
entry: 'electron/main.js',
|
||||||
vite: merge({}, args),
|
vite: mergeCommon({}, args),
|
||||||
},
|
},
|
||||||
preload: {
|
preload: {
|
||||||
input: 'electron/preload.js',
|
input: 'electron/preload.js',
|
||||||
vite: merge({}, args),
|
vite: mergeCommon({}, args),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
useRenderer(),
|
useRenderer(),
|
||||||
@ -69,3 +69,4 @@ export default args =>
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user