Skip to content

Commit

Permalink
feat(ux): support native space key to page down, fixed #1121
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Oct 27, 2024
1 parent 5a8725b commit baa66fe
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Focusable } from "@follow/components/common/Focusable.js"
import { SYSTEM_CAN_UNDER_BLUR_WINDOW } from "@follow/shared/constants"
import { cn } from "@follow/utils/utils"

Expand All @@ -7,15 +8,15 @@ type Props = Component<
React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
>
const MacOSVibrancy: Props = ({ className, children, ...rest }) => (
<div className={cn("bg-native/30 dark:bg-native/10", className)} {...rest}>
<Focusable className={cn("bg-native/30 dark:bg-native/10", className)} {...rest}>
{children}
</div>
</Focusable>
)

const Noop: Props = ({ children, className, ...rest }) => (
<div className={cn("bg-native", className)} {...rest}>
<Focusable className={cn("bg-native", className)} {...rest}>
{children}
</div>
</Focusable>
)

// Disable blur effect on Windows, because electron backgroundMaterial has some issues
Expand Down
16 changes: 2 additions & 14 deletions apps/renderer/src/components/ui/media/VideoPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Focusable, useFocusable } from "@follow/components/common/Focusable.js"
import { Focusable } from "@follow/components/common/Focusable.js"
import { ActionButton, MotionButtonBase } from "@follow/components/ui/button/index.js"
import type { HTMLMediaState } from "@follow/hooks"
import { useRefValue, useVideo } from "@follow/hooks"
Expand Down Expand Up @@ -427,25 +427,13 @@ const ActionIcon = ({
children?: React.ReactNode
shortcut?: string
}) => {
const isFocusWithIn = useFocusable()

useHotkeys(
shortcut || "",
(e) => {
e.preventDefault()
onClick?.()
},
{
enabled: isFocusWithIn,
},
)
return (
<ActionButton
shortcutOnlyFocusWithIn
tooltipSide="top"
className={clsx("z-[2] hover:bg-transparent", className)}
onClick={onClick}
tooltip={label}
disableTriggerShortcut
shortcut={shortcut}
>
{children || <i className={className} />}
Expand Down
11 changes: 1 addition & 10 deletions apps/renderer/src/modules/entry-content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { FallbackRender } from "@sentry/react"
import { ErrorBoundary } from "@sentry/react"
import type { FC } from "react"
import { memo, useEffect, useLayoutEffect, useMemo, useRef } from "react"
import { useHotkeys } from "react-hotkeys-hook"
import { useTranslation } from "react-i18next"

import {
Expand All @@ -27,7 +26,6 @@ import { ShadowDOM } from "~/components/common/ShadowDOM"
import { Toc } from "~/components/ui/markdown/components/Toc"
import { useInPeekModal } from "~/components/ui/modal/inspire/PeekModal"
import { isWebBuild } from "~/constants"
import { shortcuts } from "~/constants/shortcuts"
import { useEntryReadabilityToggle } from "~/hooks/biz/useEntryActions"
import { useRouteParamsSelector } from "~/hooks/biz/useRouteParams"
import { useAuthQuery } from "~/hooks/common"
Expand Down Expand Up @@ -122,16 +120,9 @@ export const EntryContentRender: Component<{
const scrollerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
scrollerRef.current?.scrollTo(0, 0)
scrollerRef.current?.focus()
}, [entryId])

useHotkeys(shortcuts.entry.scrollDown.key, () => {
scrollerRef.current?.scrollBy(0, window.innerHeight / 2)
})

useHotkeys(shortcuts.entry.scrollUp.key, () => {
scrollerRef.current?.scrollBy(0, -window.innerHeight / 2)
})

const isPeekModal = useInPeekModal()

const contentAccessories = useMemo(
Expand Down
3 changes: 3 additions & 0 deletions apps/renderer/src/modules/feed-column/corner-player.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useFocusable } from "@follow/components/common/Focusable.js"
import { Tooltip, TooltipContent, TooltipTrigger } from "@follow/components/ui/tooltip/index.jsx"
import { FeedViewType } from "@follow/constants"
import { cn } from "@follow/utils/utils"
Expand Down Expand Up @@ -102,9 +103,11 @@ const CornerPlayerImpl = () => {
const feed = useFeedById(entry?.feedId)
const list = useListById(listId)

const isFocused = useFocusable()
useHotkeys("space", handleClickPlay, {
preventDefault: true,
scopes: HotKeyScopeMap.Home,
enabled: isFocused,
})

useEffect(() => {
Expand Down
29 changes: 26 additions & 3 deletions packages/components/src/ui/button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useFocusable } from "@follow/components/common/Focusable"
import { LoadingCircle } from "@follow/components/ui/loading/index.jsx"
import { stopPropagation } from "@follow/utils/dom"
import { cn, getOS } from "@follow/utils/utils"
import type { VariantProps } from "class-variance-authority"
import type { HTMLMotionProps } from "framer-motion"
import { m } from "framer-motion"
import * as React from "react"
import type { Options } from "react-hotkeys-hook"
import { useHotkeys } from "react-hotkeys-hook"
import type { OptionsOrDependencyArray } from "react-hotkeys-hook/dist/types"

import { KbdCombined } from "../kbd/Kbd"
import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger } from "../tooltip"
Expand All @@ -27,6 +28,12 @@ interface ActionButtonProps {
shortcut?: string
disableTriggerShortcut?: boolean
size?: "sm" | "md" | "base"

/**
* @description only trigger shortcut when focus with in `<Focusable />`
* @default false
*/
shortcutOnlyFocusWithIn?: boolean
}

const actionButtonStyleVariant = {
Expand All @@ -52,6 +59,7 @@ export const ActionButton = React.forwardRef<
disabled,
disableTriggerShortcut,
size = "base",
shortcutOnlyFocusWithIn,
...rest
},
ref,
Expand Down Expand Up @@ -87,10 +95,15 @@ export const ActionButton = React.forwardRef<
{children}
</button>
)

return (
<>
{finalShortcut && !disableTriggerShortcut && (
<HotKeyTrigger shortcut={finalShortcut} fn={() => buttonRef.current?.click()} />
<HotKeyTrigger
shortcut={finalShortcut}
fn={() => buttonRef.current?.click()}
shortcutOnlyFocusWithIn={shortcutOnlyFocusWithIn}
/>
)}
{tooltip ? (
<Tooltip disableHoverableContent>
Expand Down Expand Up @@ -120,13 +133,23 @@ const HotKeyTrigger = ({
shortcut,
fn,
options,
shortcutOnlyFocusWithIn,
}: {
shortcut: string
fn: () => void
options?: OptionsOrDependencyArray
options?: Options
shortcutOnlyFocusWithIn?: boolean
}) => {
const isFocusWithIn = useFocusable()
const enabledInOptions = options?.enabled || true

useHotkeys(shortcut, fn, {
preventDefault: true,
enabled: shortcutOnlyFocusWithIn
? isFocusWithIn
? enabledInOptions
: false
: enabledInOptions,
...options,
})
return null
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/ui/scroll-area/ScrollArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const Viewport = React.forwardRef<
<ScrollAreaBase.Viewport
{...rest}
ref={ref}
tabIndex={-1}
className={cn("block size-full", shouldAddMask && styles["mask-scroller"], className)}
/>
)
Expand Down

0 comments on commit baa66fe

Please sign in to comment.