diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b8bb99..860a48d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,9 +3,11 @@
### Features
* 兼容移动端UI
+* 新增移动端虚拟功能按键映射
* 调整终端功能菜单
* 修复终端选中文本无法复制的bug
* 修复无法展示服务端ping客户端延迟ms的bug
+* 修复暗黑模式下的一些样式问题
## [2.2.7](https://github.com/chaos-zhu/easynode/releases) (2024-10-17)
diff --git a/web/src/assets/scss/element/dark.scss b/web/src/assets/scss/element/dark.scss
index 37897a0..b5f8cea 100644
--- a/web/src/assets/scss/element/dark.scss
+++ b/web/src/assets/scss/element/dark.scss
@@ -79,6 +79,9 @@ html.dark {
background-color: #6d6d6d;
}
+ .el-menu {
+ border-right: none;
+ }
.el-menu-item:not(.is-active):hover {
color: var(--el-menu-active-color);
}
diff --git a/web/src/components/float-menu/index.vue b/web/src/components/float-menu/index.vue
new file mode 100644
index 0000000..b619566
--- /dev/null
+++ b/web/src/components/float-menu/index.vue
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
diff --git a/web/src/utils/enum.js b/web/src/utils/enum.js
index f65b1ca..1516452 100644
--- a/web/src/utils/enum.js
+++ b/web/src/utils/enum.js
@@ -11,5 +11,7 @@ export const terminalStatusList = [
{ value: terminalStatus.CONNECT_FAIL, label: '连接失败', color: '#DC3545' },
{ value: terminalStatus.CONNECT_SUCCESS, label: '已连接', color: '#28A745' },
]
-
-// other...
+export const virtualKeyType = {
+ LONG_PRESS: 'long-press',
+ SINGLE_PRESS: 'single-press'
+}
diff --git a/web/src/views/terminal/components/terminal-tab.vue b/web/src/views/terminal/components/terminal-tab.vue
index 9138357..acabdd5 100644
--- a/web/src/views/terminal/components/terminal-tab.vue
+++ b/web/src/views/terminal/components/terminal-tab.vue
@@ -33,10 +33,18 @@ const props = defineProps({
hostObj: {
required: true,
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 commandHistoryList = ref([])
@@ -64,6 +72,8 @@ const menuCollapse = computed(() => $store.menuCollapse)
const quickCopy = computed(() => $store.terminalConfig.quickCopy)
const quickPaste = computed(() => $store.terminalConfig.quickPaste)
const autoExecuteScript = computed(() => $store.terminalConfig.autoExecuteScript)
+const isLongPressCtrl = computed(() => props.longPressCtrl)
+const isLongPressAlt = computed(() => props.longPressAlt)
watch(menuCollapse, () => {
nextTick(() => {
@@ -326,7 +336,21 @@ function extractLastCdPath(text) {
const onData = () => {
// term.value.off('data', listenerInput)
term.value.onData((key) => {
+ // console.log('key: ', key)
+ // if (key === '\x03') console.log('Ctrl + C detected')
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()
// console.log(acsiiCode)
if (acsiiCode === 22) return handlePaste() // Ctrl + V
diff --git a/web/src/views/terminal/components/terminal.vue b/web/src/views/terminal/components/terminal.vue
index 5f2191f..eb49839 100644
--- a/web/src/views/terminal/components/terminal.vue
+++ b/web/src/views/terminal/components/terminal.vue
@@ -155,9 +155,12 @@
+
+
+
+
+
@@ -185,7 +199,8 @@ import { ref, computed, getCurrentInstance, watch, onMounted, onBeforeUnmount, n
import { ArrowDown } from '@element-plus/icons-vue'
import useMobileWidth from '@/composables/useMobileWidth'
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 InfoSide from './info-side.vue'
import Sftp from './sftp.vue'
@@ -217,6 +232,9 @@ const hostFormVisible = ref(false)
const updateHostData = ref(null)
const showSetting = ref(false)
const showMobileInfoSideDialog = ref(false)
+const showFloatMenu = ref(false)
+const longPressCtrl = ref(false)
+const longPressAlt = ref(false)
const terminalTabs = computed(() => props.terminalTabs)
const terminalTabsLen = computed(() => props.terminalTabs.length)
@@ -268,6 +286,41 @@ const handleCloseAllTab = () => {
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) => {
let { command } = scriptObj
if (!isSyncAllSession.value) return handleInputCommand(command)