mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-23 23:21:02 +01:00
perf: 🍻 Update base copilot
This commit is contained in:
parent
3dab0cc833
commit
5ac5ee6e97
63
copilot/App.vue
Normal file
63
copilot/App.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="flex flex-col absolute inset-fix-0 h-full overflow-hidden">
|
||||
<div class="py-4 px-4 flex items-center flex-none">
|
||||
<a class="block" :href="escrcpyURL" target="_blank">
|
||||
<img src="@electron/resources/build/logo.png" class="h-9" alt="" />
|
||||
</a>
|
||||
<div class="pl-2 text-sm">
|
||||
Escrcpy Copilot
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 h-0 overflow-hidden bg-gray-100">
|
||||
<el-tabs v-model="tabValue" class="el-tabs-flex" @tab-click="onTabClick">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) of tabModel"
|
||||
:key="index"
|
||||
:label="item.label"
|
||||
:name="item.value"
|
||||
lazy
|
||||
class=""
|
||||
>
|
||||
<component :is="item.value" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Transmission from './components/Transmission/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Transmission,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
escrcpyURL: 'https://github.com/viarotel-org/escrcpy',
|
||||
tabValue: 'Transmission',
|
||||
tabModel: [
|
||||
{
|
||||
label: '传输助手',
|
||||
value: 'Transmission',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onTabClick() {},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
:deep() {
|
||||
.el-tabs__header {
|
||||
@apply bg-white px-4;
|
||||
}
|
||||
.el-tabs__nav-wrap::after {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
55
copilot/components/Transmission/Message/Preset.vue
Normal file
55
copilot/components/Transmission/Message/Preset.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<Message v-bind="messageProps">
|
||||
<slot></slot>
|
||||
</Message>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Message from './index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Message,
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
messageProps() {
|
||||
let value = {}
|
||||
switch (this.type) {
|
||||
case 'server':
|
||||
value = {
|
||||
name: 'PC',
|
||||
content: this.content,
|
||||
avatar: 'computer',
|
||||
}
|
||||
break
|
||||
case 'client':
|
||||
value = {
|
||||
name: this.$attrs.name || '我的手机',
|
||||
content: this.content,
|
||||
avatar: 'mobile',
|
||||
reversed: true,
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
value = this.$attrs
|
||||
break
|
||||
}
|
||||
|
||||
return value
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
81
copilot/components/Transmission/Message/index.vue
Normal file
81
copilot/components/Transmission/Message/index.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div :class="reversed ? 'flex-row-reverse' : ''" class="flex items-start">
|
||||
<img :src="avatarURL" alt="" class="w-12 h-12 flex-none" />
|
||||
<div
|
||||
class="flex flex-col"
|
||||
:class="reversed ? 'mr-4 pl-16 items-end' : 'ml-4 pr-16'"
|
||||
>
|
||||
<div v-if="!reversed" class="mt-1 text-base">
|
||||
{{ name }}
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 shadow-el-light px-4 py-2 rounded-lg break-all overflow-hidden relative"
|
||||
>
|
||||
<slot>
|
||||
<span class="pr-1">
|
||||
{{ content }}
|
||||
</span>
|
||||
<el-icon v-if="loading" class="is-loading relative top-[2px]">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import logoURL from '@electron/resources/build/logo.png'
|
||||
import userURL from '@/assets/user.png'
|
||||
import mobileURL from '@/assets/mobile.png'
|
||||
import computerURL from '@/assets/computer.png'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
reversed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
avatar: {
|
||||
type: String,
|
||||
default: 'logo',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
avatarURL() {
|
||||
let value = ''
|
||||
|
||||
switch (this.avatar) {
|
||||
case 'logo':
|
||||
value = logoURL
|
||||
break
|
||||
case 'user':
|
||||
value = userURL
|
||||
break
|
||||
case 'mobile':
|
||||
value = mobileURL
|
||||
break
|
||||
case 'computer':
|
||||
value = computerURL
|
||||
break
|
||||
}
|
||||
|
||||
return value
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
177
copilot/components/Transmission/index.vue
Normal file
177
copilot/components/Transmission/index.vue
Normal file
@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="h-full flex flex-col">
|
||||
<div
|
||||
ref="chats"
|
||||
class="flex-1 h-0 space-y-4 pb-4 px-4 overflow-auto scroll-smooth"
|
||||
>
|
||||
<Message
|
||||
v-for="(item, index) of messageList"
|
||||
v-bind="{
|
||||
type: item.type,
|
||||
content: item.content,
|
||||
}"
|
||||
:key="index"
|
||||
:loading="item.$loading"
|
||||
>
|
||||
</Message>
|
||||
</div>
|
||||
<div class="flex-none px-4 py-2 bg-white">
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
placeholder="请输入想要发送的消息"
|
||||
@keyup.enter="handleSubmit"
|
||||
>
|
||||
<template #append>
|
||||
<el-button
|
||||
icon="Promotion"
|
||||
:loading="loading"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Message from './Message/Preset.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Message,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
messageList: [],
|
||||
inputValue: '',
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.getMessageData()
|
||||
await this.$nextTick()
|
||||
this.handleScroll()
|
||||
},
|
||||
methods: {
|
||||
handleScroll() {
|
||||
const chatsEl = this.$refs.chats
|
||||
chatsEl.scrollTop = chatsEl.scrollHeight
|
||||
},
|
||||
async handleSubmit() {
|
||||
if (!this.inputValue) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
|
||||
const newMessage = {
|
||||
type: 'client',
|
||||
content: this.inputValue,
|
||||
$loading: true,
|
||||
}
|
||||
|
||||
this.messageList.push(newMessage)
|
||||
|
||||
const params = {}
|
||||
const res = await this.$mockAPI(params)
|
||||
|
||||
this.loading = false
|
||||
|
||||
if (res.success) {
|
||||
this.inputValue = ''
|
||||
newMessage.$loading = false
|
||||
await this.$nextTick()
|
||||
this.handleScroll()
|
||||
}
|
||||
},
|
||||
async getMessageData() {
|
||||
const params = {
|
||||
imitate: [
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
{
|
||||
type: 'server',
|
||||
content: '你好啊',
|
||||
},
|
||||
{
|
||||
type: 'client',
|
||||
content: '你也好啊',
|
||||
},
|
||||
],
|
||||
}
|
||||
const res = await this.$mockAPI(params)
|
||||
|
||||
if (res.success) {
|
||||
this.messageList = res.data.map(item => ({
|
||||
...item,
|
||||
$loading: false,
|
||||
}))
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,10 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark">
|
||||
<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-Server</title>
|
||||
<title>Escrcpy Copilot</title>
|
||||
</head>
|
||||
<body class="">
|
||||
<div id="app"></div>
|
37
copilot/main.js
Normal file
37
copilot/main.js
Normal file
@ -0,0 +1,37 @@
|
||||
import { createApp, toRaw } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { i18n, t } from '@/locales/index.js'
|
||||
import plugins from '@/plugins/index.js'
|
||||
import icons from '@/icons/index.js'
|
||||
|
||||
import { replaceIP, restoreIP } from '@/utils/index.js'
|
||||
|
||||
import 'virtual:uno.css'
|
||||
import '@/styles/index.js'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(plugins)
|
||||
|
||||
app.use(icons)
|
||||
|
||||
app.use(i18n)
|
||||
window.t = t
|
||||
|
||||
app.config.globalProperties.$replaceIP = replaceIP
|
||||
app.config.globalProperties.$restoreIP = restoreIP
|
||||
|
||||
app.config.globalProperties.$toRaw = toRaw
|
||||
|
||||
app.config.globalProperties.$mockAPI = ({ imitate = {}, delay = 500 } = {}) =>
|
||||
new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
code: '0000',
|
||||
data: imitate,
|
||||
success: true,
|
||||
})
|
||||
}, delay)
|
||||
})
|
||||
|
||||
app.mount('#app')
|
@ -7,14 +7,14 @@ export default async (mainWindow) => {
|
||||
const app = new Hono()
|
||||
|
||||
app.notFound((c) => {
|
||||
return c.text('Escrcpy server 404', 404)
|
||||
return c.text('Escrcpy copilot 404', 404)
|
||||
})
|
||||
|
||||
const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
|
||||
|
||||
if (VITE_DEV_SERVER_URL) {
|
||||
app.get('/', ctx =>
|
||||
ctx.redirect(`${VITE_DEV_SERVER_URL}server/index.html`),
|
||||
ctx.redirect(`${VITE_DEV_SERVER_URL}copilot/index.html`),
|
||||
)
|
||||
}
|
||||
else {
|
||||
@ -23,7 +23,7 @@ export default async (mainWindow) => {
|
||||
serveStatic({
|
||||
root: relative('./', process.env.DIST),
|
||||
rewriteRequestPath: (path) => {
|
||||
return path.replace(/^\//, '/server')
|
||||
return path.replace(/^\//, '/copilot')
|
||||
},
|
||||
}),
|
||||
)
|
@ -14,7 +14,7 @@ import { icnsLogoPath, icoLogoPath, logoPath } from './configs/index.js'
|
||||
|
||||
import events from './events/index.js'
|
||||
|
||||
import server from './server/index.js'
|
||||
import copilot from './copilot/index.js'
|
||||
|
||||
log.initialize({ preload: true })
|
||||
|
||||
@ -104,7 +104,7 @@ function createWindow() {
|
||||
|
||||
events(mainWindow)
|
||||
|
||||
server(mainWindow)
|
||||
copilot(mainWindow)
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark">
|
||||
<html lang="en" class="">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/logo.ico" />
|
||||
|
@ -3,11 +3,12 @@
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@copilot/*": ["copilot/*"],
|
||||
"@root/*": ["*"],
|
||||
"@electron/*": ["electron/*"],
|
||||
"@renderer/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist", "dist-electron", "dist-release"],
|
||||
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.vue", "electron"]
|
||||
"include": ["src", "electron", "copilot"]
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
import { createApp } from 'vue'
|
||||
|
||||
console.log('createApp', createApp)
|
BIN
src/assets/computer.png
Normal file
BIN
src/assets/computer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
BIN
src/assets/mobile.png
Normal file
BIN
src/assets/mobile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
BIN
src/assets/user.png
Normal file
BIN
src/assets/user.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -2,7 +2,7 @@ import { createI18n } from 'vue-i18n'
|
||||
import messages from '@intlify/unplugin-vue-i18n/messages'
|
||||
|
||||
const locale
|
||||
= window.appStore.get('common.language')
|
||||
= window.appStore?.get('common.language')
|
||||
|| window.electron?.process?.env?.LOCALE
|
||||
|
||||
// const locale = 'en_US'
|
||||
|
@ -3,20 +3,23 @@ html {
|
||||
}
|
||||
|
||||
/* 自定义滚动条的外观 */
|
||||
::-webkit-scrollbar {
|
||||
|
||||
@screen sm {
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: theme("colors.gray.100");
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: theme('colors.gray.100');
|
||||
@apply bg-gray-100 dark:bg-gray-800;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 9999px;
|
||||
@apply bg-gray-300 dark:bg-gray-600;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
@apply bg-gray-500 dark:bg-gray-300;
|
||||
}
|
||||
}
|
||||
|
@ -35,13 +35,14 @@ export default params =>
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: resolve(__dirname, 'index.html'),
|
||||
server: resolve(__dirname, 'server/index.html'),
|
||||
copilot: resolve(__dirname, 'copilot/index.html'),
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve('src'),
|
||||
'@copilot': resolve('copilot'),
|
||||
'@electron': resolve('electron'),
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user