mirror of
https://github.com/ayangweb/BongoCat.git
synced 2026-03-12 17:51:48 +08:00
feat: 新增「猫咪设置 > 模型设置 > 按键自动释放延迟」配置项 (#725)
This commit is contained in:
@@ -23,7 +23,10 @@ const hasDescription = computed(() => {
|
||||
justify="space-between"
|
||||
:vertical="vertical"
|
||||
>
|
||||
<Flex align="center">
|
||||
<Flex
|
||||
align="center"
|
||||
class="flex-1"
|
||||
>
|
||||
<Flex vertical>
|
||||
<div class="text-sm font-medium">
|
||||
{{ title }}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { CursorPoint } from '@/utils/monitor'
|
||||
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import { isEqual, mapValues } from 'es-toolkit'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -10,7 +9,9 @@ import { INVOKE_KEY, LISTEN_KEY } from '../constants'
|
||||
import { useModel } from './useModel'
|
||||
import { useTauriListen } from './useTauriListen'
|
||||
|
||||
import { useCatStore } from '@/stores/cat'
|
||||
import { useModelStore } from '@/stores/model'
|
||||
import { isWindows } from '@/utils/platform'
|
||||
|
||||
interface MouseButtonEvent {
|
||||
kind: 'MousePress' | 'MouseRelease'
|
||||
@@ -32,14 +33,14 @@ type DeviceEvent = MouseButtonEvent | MouseMoveEvent | KeyboardEvent
|
||||
export function useDevice() {
|
||||
const modelStore = useModelStore()
|
||||
const lastCursorPoint = ref<CursorPoint>({ x: 0, y: 0 })
|
||||
const releaseTimers = new Map<string, NodeJS.Timeout>()
|
||||
const catStore = useCatStore()
|
||||
const { handlePress, handleRelease, handleMouseChange, handleMouseMove } = useModel()
|
||||
|
||||
const startListening = () => {
|
||||
invoke(INVOKE_KEY.START_DEVICE_LISTENING)
|
||||
}
|
||||
|
||||
const debouncedRelease = useDebounceFn(handleRelease, 100)
|
||||
|
||||
const getSupportedKey = (key: string) => {
|
||||
let nextKey = key
|
||||
|
||||
@@ -69,6 +70,22 @@ export function useDevice() {
|
||||
return handleMouseMove(point)
|
||||
}
|
||||
|
||||
const handleAutoRelease = (key: string, delay = 100) => {
|
||||
handlePress(key)
|
||||
|
||||
if (releaseTimers.has(key)) {
|
||||
clearTimeout(releaseTimers.get(key))
|
||||
}
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
handleRelease(key)
|
||||
|
||||
releaseTimers.delete(key)
|
||||
}, delay)
|
||||
|
||||
releaseTimers.set(key, timer)
|
||||
}
|
||||
|
||||
useTauriListen<DeviceEvent>(LISTEN_KEY.DEVICE_CHANGED, ({ payload }) => {
|
||||
const { kind, value } = payload
|
||||
|
||||
@@ -78,12 +95,16 @@ export function useDevice() {
|
||||
if (!nextValue) return
|
||||
|
||||
if (nextValue === 'CapsLock') {
|
||||
handlePress(nextValue)
|
||||
|
||||
return debouncedRelease(nextValue)
|
||||
return handleAutoRelease(nextValue)
|
||||
}
|
||||
|
||||
if (kind === 'KeyboardPress') {
|
||||
if (isWindows) {
|
||||
const delay = catStore.model.autoReleaseDelay * 1000
|
||||
|
||||
return handleAutoRelease(nextValue, delay)
|
||||
}
|
||||
|
||||
return handlePress(nextValue)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"alwaysOnTop": "Always On Top",
|
||||
"windowSize": "Window Size",
|
||||
"windowRadius": "Window Radius",
|
||||
"opacity": "Opacity"
|
||||
"opacity": "Opacity",
|
||||
"autoReleaseDelay": "Auto Release Delay"
|
||||
},
|
||||
"hints": {
|
||||
"mirrorMode": "When enabled, the model will be horizontally flipped.",
|
||||
@@ -27,7 +28,8 @@
|
||||
"mouseMirror": "When enabled, the mouse will mirror follow the hand movement.",
|
||||
"passThrough": "When enabled, the window will not affect operations on other applications.",
|
||||
"alwaysOnTop": "When enabled, the window will always stay above other applications.",
|
||||
"windowSize": "Move the mouse to the edge of the window or hold Shift and right-drag to resize."
|
||||
"windowSize": "Move the mouse to the edge of the window or hold Shift and right-drag to resize.",
|
||||
"autoReleaseDelay": "Due to Windows not capturing the release events of certain system-level keys, they will be automatically treated as released after a timeout."
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"alwaysOnTop": "Luôn trên cùng",
|
||||
"windowSize": "Kích thước",
|
||||
"windowRadius": "Độ bo tròn cửa sổ",
|
||||
"opacity": "Độ mờ"
|
||||
"opacity": "Độ mờ",
|
||||
"autoReleaseDelay": "Độ trễ tự động nhả phím"
|
||||
},
|
||||
"hints": {
|
||||
"mirrorMode": "Bật để lật ngang mô hình.",
|
||||
@@ -27,7 +28,8 @@
|
||||
"mouseMirror": "Khi bật, chuột của mô hình sẽ phản chiếu theo chuyển động chuột thực tế.",
|
||||
"passThrough": "Bật để cửa sổ không ảnh hưởng đến thao tác trên ứng dụng khác.",
|
||||
"alwaysOnTop": "Bật để cửa sổ luôn nằm trên ứng dụng khác.",
|
||||
"windowSize": "Di chuyển chuột đến mép cửa sổ hoặc giữ Shift và kéo chuột phải để thay đổi kích thước."
|
||||
"windowSize": "Di chuyển chuột đến mép cửa sổ hoặc giữ Shift và kéo chuột phải để thay đổi kích thước.",
|
||||
"autoReleaseDelay": "Do Windows không bắt được sự kiện nhả của một số phím hệ thống, các phím đó sẽ được tự động xem như đã nhả sau khi hết thời gian chờ."
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"alwaysOnTop": "窗口置顶",
|
||||
"windowSize": "窗口尺寸",
|
||||
"windowRadius": "窗口圆角",
|
||||
"opacity": "不透明度"
|
||||
"opacity": "不透明度",
|
||||
"autoReleaseDelay": "按键自动释放延迟"
|
||||
},
|
||||
"hints": {
|
||||
"mirrorMode": "启用后,模型将水平镜像翻转。",
|
||||
@@ -27,7 +28,8 @@
|
||||
"mouseMirror": "启用后,鼠标将镜像跟随手部移动。",
|
||||
"passThrough": "启用后,窗口不影响对其他应用程序的操作。",
|
||||
"alwaysOnTop": "启用后,窗口始终显示在其他应用程序上方。",
|
||||
"windowSize": "将鼠标移至窗口边缘,或按住 Shift 并右键拖动,也可以调整窗口大小。"
|
||||
"windowSize": "将鼠标移至窗口边缘,或按住 Shift 并右键拖动,也可以调整窗口大小。",
|
||||
"autoReleaseDelay": "由于 Windows 下部分系统级按键无法捕获释放事件,超时后将自动视为已释放。"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { InputNumber, Slider, Switch } from 'ant-design-vue'
|
||||
import ProList from '@/components/pro-list/index.vue'
|
||||
import ProListItem from '@/components/pro-list-item/index.vue'
|
||||
import { useCatStore } from '@/stores/cat'
|
||||
import { isWindows } from '@/utils/platform'
|
||||
|
||||
const catStore = useCatStore()
|
||||
</script>
|
||||
@@ -30,6 +31,18 @@ const catStore = useCatStore()
|
||||
>
|
||||
<Switch v-model:checked="catStore.model.mouseMirror" />
|
||||
</ProListItem>
|
||||
|
||||
<ProListItem
|
||||
v-if="isWindows"
|
||||
:description="$t('pages.preference.cat.hints.autoReleaseDelay')"
|
||||
:title="$t('pages.preference.cat.labels.autoReleaseDelay')"
|
||||
>
|
||||
<InputNumber
|
||||
v-model:value="catStore.model.autoReleaseDelay"
|
||||
addon-after="s"
|
||||
class="w-28"
|
||||
/>
|
||||
</ProListItem>
|
||||
</ProList>
|
||||
|
||||
<ProList :title="$t('pages.preference.cat.labels.windowSettings')">
|
||||
@@ -74,7 +87,7 @@ const catStore = useCatStore()
|
||||
>
|
||||
<Slider
|
||||
v-model:value="catStore.window.opacity"
|
||||
class="m-0!"
|
||||
class="m-[0]!"
|
||||
:max="100"
|
||||
:min="10"
|
||||
:tip-formatter="(value) => `${value}%`"
|
||||
|
||||
@@ -6,6 +6,7 @@ export interface CatStore {
|
||||
mirror: boolean
|
||||
single: boolean
|
||||
mouseMirror: boolean
|
||||
autoReleaseDelay: number
|
||||
}
|
||||
window: {
|
||||
visible: boolean
|
||||
@@ -48,6 +49,7 @@ export const useCatStore = defineStore('cat', () => {
|
||||
mirror: false,
|
||||
single: false,
|
||||
mouseMirror: false,
|
||||
autoReleaseDelay: 3,
|
||||
})
|
||||
|
||||
const window = reactive<CatStore['window']>({
|
||||
|
||||
Reference in New Issue
Block a user