Skip to content

Commit

Permalink
perf: optimized key icons to font symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Mar 16, 2023
1 parent 46fa5dc commit f69235e
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 99 deletions.
3 changes: 1 addition & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
VITE_APP_NAME=ChatGPT
VITE_OPEN_AI_URL=https://api.openai.com/v1/chat/completions
VITE_OPEN_AI_API_KEY=
VITE_ICON_FONT_URL=//at.alicdn.com/t/c/font_3953740_mk2449f3r0r.js
VITE_OPEN_AI_API_KEY=
2 changes: 1 addition & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn main() {
.plugin(tauri_plugin_sql::Builder::default().build())
.plugin(tauri_plugin_autostart::init(
MacosLauncher::LaunchAgent,
Some(vec!["--flag1", "--flag2"]), /* arbitrary number of args to pass to your app */
Some(vec!["--flag1", "--flag2"]),
))
.on_system_tray_event(tray::handler)
.run(tauri::generate_context!())
Expand Down
2 changes: 1 addition & 1 deletion src/assets/css/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ body {

color: var(--color-text-1);

font: 1rem/1 sans-serif;
font: 1rem/1;
}

.bordered {
Expand Down
8 changes: 4 additions & 4 deletions src/components/Avatar/index.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import multiAvatar from '@multiavatar/multiavatar'
const props = withDefaults(defineProps<{ value?: string }>(), {
value: import.meta.env.VITE_APP_NAME
})
const props = defineProps<{ value: string }>()
const avatar = computed(() => multiAvatar(props.value || '默认头像'))
const avatar = computed(() =>
multiAvatar(props.value || import.meta.env.VITE_APP_NAME)
)
</script>

<template>
Expand Down
82 changes: 36 additions & 46 deletions src/components/Function/components/ShortcutKey.vue
Original file line number Diff line number Diff line change
@@ -1,59 +1,48 @@
<script setup lang="ts">
import { Icon } from '@arco-design/web-vue'
import { useSettingsStore } from '@/stores'
import { hotkeys, isHotKey, getKeyIcon, getKeySymbol } from '@/utils'
import { hotkeys, isHotKey, isSpecialKey, getKeySymbol } from '@/utils'
const IconFont = Icon.addFromIconFontCn({
src: import.meta.env.VITE_ICON_FONT_URL
})
const { shortcutKey, isBinding } = storeToRefs(useSettingsStore())
const { shortcutKeys, isBinding } = storeToRefs(useSettingsStore())
// 获取最后一位快捷键
const lastShortcutKey = computed(() => shortcutKey.value.at(-1) || '')
const lastShortcutKey = computed(() => shortcutKeys.value.at(-1) || '')
// 绑定快捷键的元素
const bindingElement = ref<HTMLElement | null>(null)
// 获取焦点事件
const handleFocus = () => {
shortcutKey.value = []
isBinding.value = true
}
// 键盘按下事件
const handleKeydown = (event: KeyboardEvent) => {
// key 只用在四个热键,code 用于其他的键
const { key, code } = event
const keyName = key === 'Meta' ? 'Command' : key
const codeName = isSpecialKey(code) ? code : getKeySymbol(code)!
// 不管大写锁定键
if (code === 'CapsLock') return
if (codeName === 'CapsLock') return
// 双击热键或同时按住两个相同的热键
if (shortcutKey.value.includes(key) && isHotKey(key)) {
shortcutKey.value.push(key)
if (shortcutKeys.value.includes(keyName) && isHotKey(keyName)) {
shortcutKeys.value.push(keyName)
bindingElement.value?.blur()
} else {
// 追加热键
if (isHotKey(key)) {
if (isHotKey(keyName)) {
// 如果最后一位是热键,就继续追加,反之添加到最前面
if (isHotKey(lastShortcutKey.value)) {
shortcutKey.value.push(key)
shortcutKeys.value.push(keyName)
} else {
shortcutKey.value.unshift(key)
shortcutKeys.value.unshift(keyName)
}
} else {
const codeName = getKeySymbol(code) || code
if (shortcutKeys.value.includes(codeName)) return
if (shortcutKey.value.includes(codeName)) return
shortcutKey.value.push(codeName)
shortcutKeys.value.push(codeName)
}
// 至少存在一个热键,并且保证有一个除热键之外的键
const leastOne = shortcutKey.value.some((item) => isHotKey(item))
const noEvery = shortcutKey.value.every((item) => isHotKey(item))
const leastOne = shortcutKeys.value.some((item) => isHotKey(item))
const noEvery = shortcutKeys.value.every((item) => isHotKey(item))
if (leastOne && !noEvery) {
bindingElement.value?.blur()
}
Expand All @@ -68,51 +57,52 @@ const handleKeyup = (event: KeyboardEvent) => {
setTimeout(() => {
if (!isBinding.value) return
shortcutKey.value = []
shortcutKeys.value = []
}, 300)
} else {
shortcutKey.value = []
shortcutKeys.value = []
}
}
</script>
<!-- TODO:热键绑定高度会有跳动,更换整体图标 -->
<!-- TODO: 失去焦点应该先判断有没有自定义过,没有就行把之前的再显示回来,而不是直接置为默认 -->
<template>
<div class="flex items-center gap-2">
<span>唤醒窗口:</span>
<div
ref="bindingElement"
tabindex="0"
class="text-5 flex flex-1 cursor-pointer items-center justify-between rounded border border-solid border-[var(--color-fill-2)] bg-[var(--color-fill-2)] p-2 outline-none transition"
class="flex flex-1 cursor-pointer items-center justify-between rounded border border-solid border-[var(--color-fill-2)] bg-[var(--color-fill-2)] p-2 outline-none transition"
:class="[isBinding ? 'border-[rgb(var(--primary-5))]!' : '']"
@focus="handleFocus"
@focus="isBinding = true"
@blur="isBinding = false"
@keydown="handleKeydown"
@keyup="handleKeyup"
>
<div class="flex items-center gap-2 text-[var(--color-text-4)]">
<div
class="text-6 flex items-center gap-2 font-bold leading-none text-[var(--color-text-4)]"
>
<!-- 热键 -->
<IconFont
v-for="item in hotkeys"
:type="item.icon"
<span
v-for="(item, index) of hotkeys"
:class="[
shortcutKey.includes(item.code) && 'text-[rgb(var(--primary-5))]'
shortcutKeys.includes(item.key) && 'text-[rgb(var(--primary-5))]'
]"
:key="item.code"
/>

<span
class="pl-2 leading-none text-[rgb(var(--primary-5))]"
v-if="!isBinding"
:key="index"
>
{{ item.symbol }}
</span>

<span class="pl-2 text-[rgb(var(--primary-5))]" v-if="!isBinding">
<!-- 双🐔键 -->
<template v-if="shortcutKey[0] === shortcutKey[1]">
<template v-if="shortcutKeys[0] === shortcutKeys[1]">
double tap
</template>
<!-- 特殊有图标的键 -->
<template v-else-if="getKeyIcon(lastShortcutKey)">
<IconFont :type="getKeyIcon(lastShortcutKey)" />

<!-- 特殊键 -->
<template v-else-if="isSpecialKey(lastShortcutKey)">
{{ getKeySymbol(lastShortcutKey) }}
</template>

<!-- 普通键 -->
<template v-else>
{{ lastShortcutKey }}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Session/components/NoSession.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<script setup lang="ts">
import { useSettingsStore } from '@/stores'
const { shortcutKey } = storeToRefs(useSettingsStore())
const { shortcutKeys } = storeToRefs(useSettingsStore())
</script>

<template>
<div class="text-5 flex h-full flex-col items-center justify-center gap-4">
<!-- 唤醒窗口 -->
<span>
<template v-for="(item, index) of shortcutKey" :key="index">
<template v-for="(item, index) of shortcutKeys" :key="index">
<a-typography-text code>{{ item }}</a-typography-text>
<template v-if="index < shortcutKey.length - 1"> + </template>
<template v-if="index < shortcutKeys.length - 1"> + </template>
</template>
唤醒窗口
</span>
Expand Down
27 changes: 14 additions & 13 deletions src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const useSettingsStore = defineStore(
const apiKey = ref('')

// 全局快捷键
const shortcutKey = ref<string[]>([])
const shortcutKeys = ref<string[]>([])
const isBinding = ref(false)

// 开机自启动
Expand All @@ -39,7 +39,7 @@ export const useSettingsStore = defineStore(
const registerKey = async () => {
await unregisterAll()

register(shortcutKey.value.join('+'), () => {
register(shortcutKeys.value.join('+'), () => {
appWindow.setFocus()
})
}
Expand All @@ -56,18 +56,19 @@ export const useSettingsStore = defineStore(
uuid.value = crypto.randomUUID()
})

// 监听快捷键更换
// 监听快捷键
watchEffect(() => {
if (isBinding.value || shortcutKey.value.length) return
if (isBinding.value) {
shortcutKeys.value = []

shortcutKey.value = DEFAULT_SHORTCUT_KEY
})

// 注册全局快捷键
watchEffect(() => {
if (isBinding.value) return
unregisterAll()
} else {
if (!shortcutKeys.value.length) {
shortcutKeys.value = DEFAULT_SHORTCUT_KEY
}

registerKey()
registerKey()
}
})

// 监听开机自启动
Expand All @@ -85,15 +86,15 @@ export const useSettingsStore = defineStore(
uuid,
isFix,
apiKey,
shortcutKey,
shortcutKeys,
isBinding,
autoStart,
toggleTheme
}
},
{
persist: {
paths: ['themeMode', 'uuid', 'apiKey', 'shortcutKey', 'autoStart']
paths: ['themeMode', 'uuid', 'apiKey', 'shortcutKeys', 'autoStart']
}
}
)
64 changes: 36 additions & 28 deletions src/utils/keyMap.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
// 热键列表
// 热键
export const hotkeys = [
{
code: 'Shift'
key: 'Shift',
symbol: '⇧'
},
{
code: 'Alt'
key: 'Alt',
symbol: '⌥'
},
{
code: 'Control'
key: 'Control',
symbol: '⌃'
},
{
code: 'Meta'
key: 'Command',
symbol: '⌘'
}
].map(({ code }) => ({
code,
icon: `icon-${code.toLowerCase()}`
}))
]

// 有图标的按键
export const hasIconKeys = [
// 特殊按键
export const specialKeys = [
{
code: 'Escape'
code: 'Escape',
symbol: '⎋'
},
{
code: 'Tab'
code: 'Tab',
symbol: '⇥'
},
{
code: 'Backspace'
code: 'Backspace',
symbol: '⌫'
},
{
code: 'Enter'
code: 'Enter',
symbol: '↩︎'
},
{
code: 'ArrowUp'
code: 'ArrowUp',
symbol: '⇡'
},
{
code: 'ArrowRight'
code: 'ArrowRight',
symbol: '⇢'
},
{
code: 'ArrowDown'
code: 'ArrowDown',
symbol: '⇣'
},
{
code: 'ArrowLeft'
code: 'ArrowLeft',
symbol: '⇠'
}
].map(({ code }) => ({
code,
icon: `icon-${code.toLowerCase()}`
}))
]

// 普通按键
export const generalKeys = [
Expand Down Expand Up @@ -266,21 +272,23 @@ export const generalKeys = [
* @param key 按键 key 值
*/
export const isHotKey = (key: string) => {
return !!hotkeys.find((item) => item.code === key)
return hotkeys.some((item) => item.key === key)
}

/**
* 获取按键 icon
* 判断是否为特殊键
* @param key 按键 code 值
*/
export const getKeyIcon = (code: string) => {
return hasIconKeys.find((item) => item.code === code)?.icon
export const isSpecialKey = (code: string) => {
return specialKeys.some((item) => item.code === code)
}

/**
* 获取按键符号
* @param key 按键 code 值
*/
export const getKeySymbol = (code: string) => {
return generalKeys.find((item) => item.code === code)?.symbol
const keys = [...specialKeys, ...generalKeys]

return keys.find((item) => item.code === code)?.symbol
}
1 change: 0 additions & 1 deletion src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ interface ImportMetaEnv {
readonly VITE_APP_NAME: string
readonly VITE_OPEN_AI_URL: string
readonly VITE_OPEN_AI_API_KEY: string
readonly VITE_ICON_FONT_URL: string
}

// eslint-disable-next-line no-unused-vars
Expand Down

0 comments on commit f69235e

Please sign in to comment.