✨ 新增移动端虚拟按键映射
This commit is contained in:
parent
6b5f882808
commit
fc42e1b29a
@ -3,9 +3,11 @@
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* 兼容移动端UI
|
* 兼容移动端UI
|
||||||
|
* 新增移动端虚拟功能按键映射
|
||||||
* 调整终端功能菜单
|
* 调整终端功能菜单
|
||||||
* 修复终端选中文本无法复制的bug
|
* 修复终端选中文本无法复制的bug
|
||||||
* 修复无法展示服务端ping客户端延迟ms的bug
|
* 修复无法展示服务端ping客户端延迟ms的bug
|
||||||
|
* 修复暗黑模式下的一些样式问题
|
||||||
|
|
||||||
## [2.2.7](https://github.com/chaos-zhu/easynode/releases) (2024-10-17)
|
## [2.2.7](https://github.com/chaos-zhu/easynode/releases) (2024-10-17)
|
||||||
|
|
||||||
|
@ -79,6 +79,9 @@ html.dark {
|
|||||||
background-color: #6d6d6d;
|
background-color: #6d6d6d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-menu {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
.el-menu-item:not(.is-active):hover {
|
.el-menu-item:not(.is-active):hover {
|
||||||
color: var(--el-menu-active-color);
|
color: var(--el-menu-active-color);
|
||||||
}
|
}
|
||||||
|
258
web/src/components/float-menu/index.vue
Normal file
258
web/src/components/float-menu/index.vue
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mobile_float_menu_container">
|
||||||
|
<div
|
||||||
|
class="draggable_ball"
|
||||||
|
:style="styleObject"
|
||||||
|
@touchstart="startDrag"
|
||||||
|
@click.stop="handleClick"
|
||||||
|
>
|
||||||
|
<el-icon><Calendar /></el-icon>
|
||||||
|
</div>
|
||||||
|
<el-drawer
|
||||||
|
v-model="showMenu"
|
||||||
|
direction="ttb"
|
||||||
|
:with-header="false"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
:modal="false"
|
||||||
|
modal-class="keyboard_drawer"
|
||||||
|
>
|
||||||
|
<el-divider content-position="left">组合键</el-divider>
|
||||||
|
<ul class="keyboard">
|
||||||
|
<li
|
||||||
|
v-for="item in keyGroup"
|
||||||
|
:key="item.key"
|
||||||
|
class="key"
|
||||||
|
@click="handleClickKey(item)"
|
||||||
|
>
|
||||||
|
<div>{{ item.key }}</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<el-divider content-position="left">功能键</el-divider>
|
||||||
|
<ul class="keyboard">
|
||||||
|
<li
|
||||||
|
v-for="item in keys"
|
||||||
|
:key="item.key"
|
||||||
|
:class="['key', { long_press: item.type === LONG_PRESS }]"
|
||||||
|
@click="handleClickKey(item)"
|
||||||
|
>
|
||||||
|
<div :class="{ active: (item.key === 'Ctrl' && longPressCtrl) || (item.key === 'Alt' && longPressAlt) }">
|
||||||
|
{{ item.key }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
import { Calendar } from '@element-plus/icons-vue'
|
||||||
|
import { virtualKeyType } from '@/utils/enum'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
longPressCtrl: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
longPressAlt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:show', 'click-key',])
|
||||||
|
|
||||||
|
let showMenu = computed({
|
||||||
|
get: () => props.show,
|
||||||
|
set: (newVal) => emit('update:show', newVal) })
|
||||||
|
|
||||||
|
const { LONG_PRESS, SINGLE_PRESS } = virtualKeyType
|
||||||
|
const keys = ref([
|
||||||
|
{ key: 'Esc', ascii: 27, type: SINGLE_PRESS, ansi: '\x1B' },
|
||||||
|
{ key: 'Tab', ascii: 9, type: SINGLE_PRESS, ansi: '\x09' },
|
||||||
|
{ key: 'Ctrl', ascii: null, type: LONG_PRESS, ansi: '' },
|
||||||
|
{ key: 'Alt', ascii: null, type: LONG_PRESS, ansi: '' },
|
||||||
|
{ key: 'F1', ascii: 112, type: SINGLE_PRESS, ansi: '\x1BOP' },
|
||||||
|
{ key: 'F2', ascii: 113, type: SINGLE_PRESS, ansi: '\x1BOQ' },
|
||||||
|
{ key: 'F3', ascii: 114, type: SINGLE_PRESS, ansi: '\x1BOR' },
|
||||||
|
{ key: 'F4', ascii: 115, type: SINGLE_PRESS, ansi: '\x1BOS' },
|
||||||
|
{ key: 'F5', ascii: 116, type: SINGLE_PRESS, ansi: '\x1B[15~' },
|
||||||
|
{ key: 'F6', ascii: 117, type: SINGLE_PRESS, ansi: '\x1B[17~' },
|
||||||
|
{ key: 'F7', ascii: 118, type: SINGLE_PRESS, ansi: '\x1B[18~' },
|
||||||
|
{ key: 'F8', ascii: 119, type: SINGLE_PRESS, ansi: '\x1B[19~' },
|
||||||
|
{ key: 'F9', ascii: 120, type: SINGLE_PRESS, ansi: '\x1B[20~' },
|
||||||
|
{ key: 'F10', ascii: 121, type: SINGLE_PRESS, ansi: '\x1B[21~' },
|
||||||
|
{ key: 'F11', ascii: 122, type: SINGLE_PRESS, ansi: '\x1B[23~' },
|
||||||
|
{ key: 'F12', ascii: 123, type: SINGLE_PRESS, ansi: '\x1B[24~' },
|
||||||
|
{ key: 'Backspace', ascii: 8, type: SINGLE_PRESS, ansi: '\x7F' },
|
||||||
|
{ key: 'Delete', ascii: 46, type: SINGLE_PRESS, ansi: '\x1B[3~' },
|
||||||
|
{ key: '↑', ascii: 38, type: SINGLE_PRESS, ansi: '\x1B[A' },
|
||||||
|
{ key: '→', ascii: 39, type: SINGLE_PRESS, ansi: '\x1B[C' },
|
||||||
|
{ key: 'Home', ascii: 36, type: SINGLE_PRESS, ansi: '\x1B[H' },
|
||||||
|
{ key: 'End', ascii: 35, type: SINGLE_PRESS, ansi: '\x1B[F' },
|
||||||
|
{ key: '↓', ascii: 40, type: SINGLE_PRESS, ansi: '\x1B[B' },
|
||||||
|
{ key: '←', ascii: 37, type: SINGLE_PRESS, ansi: '\x1B[D' },
|
||||||
|
{ key: 'PageUp', ascii: 33, type: SINGLE_PRESS, ansi: '\x1B[5~' },
|
||||||
|
{ key: 'PageDown', ascii: 34, type: SINGLE_PRESS, ansi: '\x1B[6~' },
|
||||||
|
])
|
||||||
|
|
||||||
|
const keyGroup = ref([
|
||||||
|
{ key: 'Ctrl+C', ascii: null, type: SINGLE_PRESS, ansi: '\x03' },
|
||||||
|
{ key: 'Ctrl+A', ascii: null, type: SINGLE_PRESS, ansi: '\x01' },
|
||||||
|
{ key: 'Ctrl+E', ascii: null, type: SINGLE_PRESS, ansi: '\x05' },
|
||||||
|
{ key: 'Ctrl+L', ascii: null, type: SINGLE_PRESS, ansi: '\x0C' },
|
||||||
|
{ key: 'Ctrl+R', ascii: null, type: SINGLE_PRESS, ansi: '\x12' },
|
||||||
|
{ key: ':wq', ascii: null, type: SINGLE_PRESS, ansi: ':wq\r' },
|
||||||
|
{ key: ':q!', ascii: null, type: SINGLE_PRESS, ansi: ':q!\r' },
|
||||||
|
{ key: 'dd', ascii: null, type: SINGLE_PRESS, ansi: 'dd\r' },
|
||||||
|
])
|
||||||
|
|
||||||
|
const handleClickKey = (key) => {
|
||||||
|
emit('click-key', key)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
showMenu.value = !showMenu.value
|
||||||
|
// if (!dragging || (Math.abs(initialX - x.value) < 10 && Math.abs(initialY - y.value) < 10)) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
const radius = 20 // 悬浮球的半径
|
||||||
|
const x = ref(window.innerWidth - radius * 2) // 初始化位置在屏幕右下角
|
||||||
|
const y = ref(window.innerHeight - radius * 2)
|
||||||
|
|
||||||
|
const styleObject = ref({
|
||||||
|
position: 'fixed',
|
||||||
|
top: `${ y.value }px`,
|
||||||
|
left: `${ x.value }px`,
|
||||||
|
cursor: 'grab',
|
||||||
|
userSelect: 'none',
|
||||||
|
width: `${ radius * 2 }px`, // 悬浮球的直径
|
||||||
|
height: `${ radius * 2 }px`,
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: '#42b983',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '14px',
|
||||||
|
zIndex: '1000'
|
||||||
|
})
|
||||||
|
|
||||||
|
let startX = 0
|
||||||
|
let startY = 0
|
||||||
|
let dragging = false
|
||||||
|
let initialX = 0 // 初始化点击位置X
|
||||||
|
let initialY = 0 // 初始化点击位置Y
|
||||||
|
|
||||||
|
const startDrag = (event) => {
|
||||||
|
const touchEvent = event.type.includes('touch') ? event.touches[0] : event
|
||||||
|
dragging = true
|
||||||
|
initialX = touchEvent.clientX
|
||||||
|
initialY = touchEvent.clientY
|
||||||
|
startX = touchEvent.clientX - x.value
|
||||||
|
startY = touchEvent.clientY - y.value
|
||||||
|
if (event.type.includes('touch')) {
|
||||||
|
document.addEventListener('touchmove', onDragging)
|
||||||
|
document.addEventListener('touchend', stopDrag)
|
||||||
|
} else {
|
||||||
|
document.addEventListener('mousemove', onDragging)
|
||||||
|
document.addEventListener('mouseup', stopDrag)
|
||||||
|
}
|
||||||
|
// event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDragging = (event) => {
|
||||||
|
if (dragging) {
|
||||||
|
const moveEvent = event.type.includes('touch') ? event.touches[0] : event
|
||||||
|
let newX = moveEvent.clientX - startX
|
||||||
|
let newY = moveEvent.clientY - startY
|
||||||
|
|
||||||
|
// 边界检查以保持悬浮球至少露出一半
|
||||||
|
newX = Math.max(newX, -radius) // 允许悬浮球露出一半
|
||||||
|
newX = Math.min(newX, window.innerWidth - radius) // 确保右侧至少露出一半
|
||||||
|
newY = Math.max(newY, -radius) // 允许悬浮球露出一半
|
||||||
|
newY = Math.min(newY, window.innerHeight - radius) // 确保底部至少露出一半
|
||||||
|
|
||||||
|
x.value = newX
|
||||||
|
y.value = newY
|
||||||
|
styleObject.value.top = `${ y.value }px`
|
||||||
|
styleObject.value.left = `${ x.value }px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopDrag = (event) => {
|
||||||
|
dragging = false
|
||||||
|
if (event.type.includes('touch')) {
|
||||||
|
document.removeEventListener('touchmove', onDragging)
|
||||||
|
document.removeEventListener('touchend', stopDrag)
|
||||||
|
} else {
|
||||||
|
document.removeEventListener('mousemove', onDragging)
|
||||||
|
document.removeEventListener('mouseup', stopDrag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保组件在初始加载时位于右下角
|
||||||
|
onMounted(() => {
|
||||||
|
x.value = window.innerWidth - radius * 2
|
||||||
|
y.value = window.innerHeight - radius * 2
|
||||||
|
styleObject.value.top = `${ y.value }px`
|
||||||
|
styleObject.value.left = `${ x.value }px`
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.mobile_float_menu_container {
|
||||||
|
.draggable_ball {
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
&:active,
|
||||||
|
&:touch-active {
|
||||||
|
background-color: #333;
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyboard_drawer {
|
||||||
|
height: 25vh;
|
||||||
|
.el-drawer {
|
||||||
|
height: 100%!important;
|
||||||
|
.el-drawer__header {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.el-drawer__body {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.keyboard {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 0;
|
||||||
|
.key {
|
||||||
|
width: 80px;
|
||||||
|
font-size: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
min-height: 15px;
|
||||||
|
}
|
||||||
|
.long_press {
|
||||||
|
.active {
|
||||||
|
// color: red;
|
||||||
|
font-weight: bolder;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -11,5 +11,7 @@ export const terminalStatusList = [
|
|||||||
{ value: terminalStatus.CONNECT_FAIL, label: '连接失败', color: '#DC3545' },
|
{ value: terminalStatus.CONNECT_FAIL, label: '连接失败', color: '#DC3545' },
|
||||||
{ value: terminalStatus.CONNECT_SUCCESS, label: '已连接', color: '#28A745' },
|
{ value: terminalStatus.CONNECT_SUCCESS, label: '已连接', color: '#28A745' },
|
||||||
]
|
]
|
||||||
|
export const virtualKeyType = {
|
||||||
// other...
|
LONG_PRESS: 'long-press',
|
||||||
|
SINGLE_PRESS: 'single-press'
|
||||||
|
}
|
||||||
|
@ -33,10 +33,18 @@ const props = defineProps({
|
|||||||
hostObj: {
|
hostObj: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
|
},
|
||||||
|
longPressCtrl: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
longPressAlt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['inputCommand', 'cdCommand', 'ping-data',])
|
const emit = defineEmits(['inputCommand', 'cdCommand', 'ping-data', 'reset-long-press',])
|
||||||
|
|
||||||
const socket = ref(null)
|
const socket = ref(null)
|
||||||
// const commandHistoryList = ref([])
|
// const commandHistoryList = ref([])
|
||||||
@ -64,6 +72,8 @@ const menuCollapse = computed(() => $store.menuCollapse)
|
|||||||
const quickCopy = computed(() => $store.terminalConfig.quickCopy)
|
const quickCopy = computed(() => $store.terminalConfig.quickCopy)
|
||||||
const quickPaste = computed(() => $store.terminalConfig.quickPaste)
|
const quickPaste = computed(() => $store.terminalConfig.quickPaste)
|
||||||
const autoExecuteScript = computed(() => $store.terminalConfig.autoExecuteScript)
|
const autoExecuteScript = computed(() => $store.terminalConfig.autoExecuteScript)
|
||||||
|
const isLongPressCtrl = computed(() => props.longPressCtrl)
|
||||||
|
const isLongPressAlt = computed(() => props.longPressAlt)
|
||||||
|
|
||||||
watch(menuCollapse, () => {
|
watch(menuCollapse, () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@ -326,7 +336,21 @@ function extractLastCdPath(text) {
|
|||||||
const onData = () => {
|
const onData = () => {
|
||||||
// term.value.off('data', listenerInput)
|
// term.value.off('data', listenerInput)
|
||||||
term.value.onData((key) => {
|
term.value.onData((key) => {
|
||||||
|
// console.log('key: ', key)
|
||||||
|
// if (key === '\x03') console.log('Ctrl + C detected')
|
||||||
if (socketConnected.value === false) return
|
if (socketConnected.value === false) return
|
||||||
|
if (isLongPressCtrl.value || isLongPressAlt.value) {
|
||||||
|
const keyCode = key.toUpperCase().charCodeAt(0)
|
||||||
|
const ansiCode = keyCode - 64
|
||||||
|
// console.log('ansiCode:', ansiCode)
|
||||||
|
if (ansiCode >= 1 && ansiCode <= 26) {
|
||||||
|
const controlChar = String.fromCharCode(ansiCode)
|
||||||
|
socket.value.emit('input', controlChar)
|
||||||
|
}
|
||||||
|
emit('reset-long-press')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let acsiiCode = key.codePointAt()
|
let acsiiCode = key.codePointAt()
|
||||||
// console.log(acsiiCode)
|
// console.log(acsiiCode)
|
||||||
if (acsiiCode === 22) return handlePaste() // Ctrl + V
|
if (acsiiCode === 22) return handlePaste() // Ctrl + V
|
||||||
|
@ -155,9 +155,12 @@
|
|||||||
<TerminalTab
|
<TerminalTab
|
||||||
ref="terminalRefs"
|
ref="terminalRefs"
|
||||||
:host-obj="item"
|
:host-obj="item"
|
||||||
|
:long-press-ctrl="longPressCtrl"
|
||||||
|
:long-press-alt="longPressAlt"
|
||||||
@input-command="terminalInput"
|
@input-command="terminalInput"
|
||||||
@cd-command="cdCommand"
|
@cd-command="cdCommand"
|
||||||
@ping-data="getPingData"
|
@ping-data="getPingData"
|
||||||
|
@reset-long-press="resetLongPress"
|
||||||
/>
|
/>
|
||||||
<Sftp
|
<Sftp
|
||||||
v-if="showSftp"
|
v-if="showSftp"
|
||||||
@ -169,14 +172,25 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InputCommand v-model:show="showInputCommand" @input-command="handleInputCommand" />
|
<InputCommand v-model:show="showInputCommand" @input-command="handleInputCommand" />
|
||||||
|
|
||||||
<HostForm
|
<HostForm
|
||||||
v-model:show="hostFormVisible"
|
v-model:show="hostFormVisible"
|
||||||
:default-data="updateHostData"
|
:default-data="updateHostData"
|
||||||
@update-list="handleUpdateList"
|
@update-list="handleUpdateList"
|
||||||
@closed="updateHostData = null"
|
@closed="updateHostData = null"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TerminalSetting v-model:show="showSetting" />
|
<TerminalSetting v-model:show="showSetting" />
|
||||||
|
|
||||||
|
<FloatMenu
|
||||||
|
v-if="isMobileScreen"
|
||||||
|
v-model:show="showFloatMenu"
|
||||||
|
:long-press-ctrl="longPressCtrl"
|
||||||
|
:long-press-alt="longPressAlt"
|
||||||
|
@click-key="handleClickVirtualKeyboard"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -185,7 +199,8 @@ import { ref, computed, getCurrentInstance, watch, onMounted, onBeforeUnmount, n
|
|||||||
import { ArrowDown } from '@element-plus/icons-vue'
|
import { ArrowDown } from '@element-plus/icons-vue'
|
||||||
import useMobileWidth from '@/composables/useMobileWidth'
|
import useMobileWidth from '@/composables/useMobileWidth'
|
||||||
import InputCommand from '@/components/input-command/index.vue'
|
import InputCommand from '@/components/input-command/index.vue'
|
||||||
import { terminalStatusList } from '@/utils/enum'
|
import FloatMenu from '@/components/float-menu/index.vue'
|
||||||
|
import { terminalStatusList, virtualKeyType } from '@/utils/enum'
|
||||||
import TerminalTab from './terminal-tab.vue'
|
import TerminalTab from './terminal-tab.vue'
|
||||||
import InfoSide from './info-side.vue'
|
import InfoSide from './info-side.vue'
|
||||||
import Sftp from './sftp.vue'
|
import Sftp from './sftp.vue'
|
||||||
@ -217,6 +232,9 @@ const hostFormVisible = ref(false)
|
|||||||
const updateHostData = ref(null)
|
const updateHostData = ref(null)
|
||||||
const showSetting = ref(false)
|
const showSetting = ref(false)
|
||||||
const showMobileInfoSideDialog = ref(false)
|
const showMobileInfoSideDialog = ref(false)
|
||||||
|
const showFloatMenu = ref(false)
|
||||||
|
const longPressCtrl = ref(false)
|
||||||
|
const longPressAlt = ref(false)
|
||||||
|
|
||||||
const terminalTabs = computed(() => props.terminalTabs)
|
const terminalTabs = computed(() => props.terminalTabs)
|
||||||
const terminalTabsLen = computed(() => props.terminalTabs.length)
|
const terminalTabsLen = computed(() => props.terminalTabs.length)
|
||||||
@ -268,6 +286,41 @@ const handleCloseAllTab = () => {
|
|||||||
emit('close-all-tab')
|
emit('close-all-tab')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { LONG_PRESS, SINGLE_PRESS } = virtualKeyType
|
||||||
|
const handleClickVirtualKeyboard = async (virtualKey) => {
|
||||||
|
const { key, ansi ,type } = virtualKey
|
||||||
|
// console.log(key, ascii, ansi, type)
|
||||||
|
switch (type) {
|
||||||
|
case LONG_PRESS:
|
||||||
|
// console.log('待组合键')
|
||||||
|
if (key === 'Ctrl') {
|
||||||
|
longPressCtrl.value = true
|
||||||
|
longPressAlt.value = false
|
||||||
|
}
|
||||||
|
if (key === 'Alt') {
|
||||||
|
longPressAlt.value = true
|
||||||
|
longPressCtrl.value = false
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-case-declarations
|
||||||
|
const curTerminalRef = terminalRefs.value[activeTabIndex.value]
|
||||||
|
await $nextTick()
|
||||||
|
curTerminalRef?.focusTab()
|
||||||
|
break
|
||||||
|
case SINGLE_PRESS:
|
||||||
|
longPressCtrl.value = false
|
||||||
|
longPressAlt.value = false
|
||||||
|
handleExecScript({ command: ansi })
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetLongPress = () => {
|
||||||
|
longPressCtrl.value = false
|
||||||
|
longPressAlt.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const handleExecScript = (scriptObj) => {
|
const handleExecScript = (scriptObj) => {
|
||||||
let { command } = scriptObj
|
let { command } = scriptObj
|
||||||
if (!isSyncAllSession.value) return handleInputCommand(command)
|
if (!isSyncAllSession.value) return handleInputCommand(command)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user