Skip to content

Commit

Permalink
fix: when comand pressed, skip peek, fixed #436
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Aug 21, 2024
1 parent 2878220 commit 27b0fdc
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/components/modules/peek/PeekLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { usePathname } from 'next/navigation'
import type { FC, PropsWithChildren, SyntheticEvent } from 'react'
import { useCallback } from 'react'

import useIsCommandOrControlPressed from '~/hooks/common/use-is-command-or-control-pressed'
import { preventDefault } from '~/lib/dom'
import { Routes } from '~/lib/route-builder'

Expand All @@ -21,16 +22,18 @@ export const PeekLink: FC<
const peek = usePeek()

const pathname = usePathname()
const isCommandPressed = useIsCommandOrControlPressed()

const handlePeek = useCallback(
async (e: SyntheticEvent) => {
if (pathname === '/' || pathname === Routes.Posts) {
return
}
if (isCommandPressed) return
const success = peek(href)
if (success) preventDefault(e)
},
[href, pathname, peek],
[href, isCommandPressed, pathname, peek],
)

return (
Expand Down
6 changes: 5 additions & 1 deletion src/components/ui/link-card/LinkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { MingcuteStarHalfFill } from '~/components/icons/star'
import { usePeek } from '~/components/modules/peek/usePeek'
import { LanguageToColorMap } from '~/constants/language'
import { useIsClientTransition } from '~/hooks/common/use-is-client'
import useIsCommandOrControlPressed from '~/hooks/common/use-is-command-or-control-pressed'
import { preventDefault } from '~/lib/dom'
import { fetchGitHubApi } from '~/lib/github'
import { clsxm } from '~/lib/helper'
Expand Down Expand Up @@ -72,12 +73,15 @@ const LinkCardImpl: FC<LinkCardProps> = (props) => {
const [cardInfo, setCardInfo] = useState<CardState>()

const peek = usePeek()
const isCommandPressed = useIsCommandOrControlPressed()

const handleCanPeek = useCallback(
async (e: SyntheticEvent<any>) => {
if (isCommandPressed) return
const success = peek(fullUrl)
if (success) preventDefault(e)
},
[fullUrl],
[fullUrl, isCommandPressed, peek],
)

const tmdbEnabled = useFeatureEnabled('tmdb')
Expand Down
57 changes: 57 additions & 0 deletions src/hooks/common/use-is-command-or-control-pressed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useEffect, useState } from 'react'

let globalIsPressed = false
let listeners = [] as ((isPressed: boolean) => void)[]

function notifyListeners() {
listeners.forEach((listener) => listener(globalIsPressed))
}

function handleKeyDown(event: KeyboardEvent) {
if ((event.metaKey || event.ctrlKey) && !globalIsPressed) {
globalIsPressed = true
notifyListeners()
}
}

function handleKeyUp() {
if (globalIsPressed) {
globalIsPressed = false
notifyListeners()
}
}

function addListener(listener: (isPressed: boolean) => void) {
listeners.push(listener)
listener(globalIsPressed)
}

function removeListener(listener: (isPressed: boolean) => void) {
listeners = listeners.filter((l) => l !== listener)
}

export function useIsCommandOrControlPressed() {
const [isPressed, setIsPressed] = useState(globalIsPressed)

useEffect(() => {
addListener(setIsPressed)

if (listeners.length === 1) {
window.addEventListener('keydown', handleKeyDown)
window.addEventListener('keyup', handleKeyUp)
}

return () => {
removeListener(setIsPressed)

if (listeners.length === 0) {
window.removeEventListener('keydown', handleKeyDown)
window.removeEventListener('keyup', handleKeyUp)
}
}
}, [])

return isPressed
}

export default useIsCommandOrControlPressed

0 comments on commit 27b0fdc

Please sign in to comment.