feat: enable hover to read after hovering list for 1 second

This commit is contained in:
DIYgod 2024-05-30 01:30:21 +08:00
parent 035093e411
commit 56e3df3fe5
No known key found for this signature in database
2 changed files with 37 additions and 4 deletions

View File

@ -2,8 +2,9 @@ import { Tabs, TabsList, TabsTrigger } from "@renderer/components/ui/tabs"
import { cn } from "@renderer/lib/utils"
import { useEntries } from "@renderer/queries/entries"
import { useFeedStore } from "@renderer/store"
import { useHover } from "@use-gesture/react"
import { m } from "framer-motion"
import { useState } from "react"
import { useRef, useState } from "react"
import { ArticleItem } from "./article-item"
import { EntryItemWrapper } from "./item-wrapper"
@ -16,6 +17,7 @@ const gridMode = new Set([2, 3])
export function EntryColumn() {
const [filterTab, setFilterTab] = useState("unread")
const [focused, setFocused] = useState(false)
const activeList = useFeedStore((state) => state.activeList)
const entries = useEntries({
@ -25,6 +27,26 @@ export function EntryColumn() {
...(filterTab === "unread" && { read: false }),
})
const listRef = useRef<HTMLDivElement>(null)
let focuseTimer: NodeJS.Timeout | null = null
useHover(
(state) => {
if (state.active) {
focuseTimer = setTimeout(() => {
setFocused(true)
}, 1000)
} else {
if (focuseTimer) {
clearTimeout(focuseTimer)
}
setFocused(false)
}
},
{
target: listRef,
},
)
let Item
switch (activeList?.view) {
case 0: {
@ -70,7 +92,7 @@ export function EntryColumn() {
</TabsList>
</Tabs>
</div>
<div>
<div ref={listRef}>
{entries.data?.pages?.map((page) => (
<m.div
key={`${activeList?.level}-${activeList?.id}`}
@ -88,6 +110,7 @@ export function EntryColumn() {
key={entry.entries.id}
entry={entry}
view={activeList?.view}
hoverToRead={focused}
>
<Item entry={entry} />
</EntryItemWrapper>

View File

@ -7,16 +7,18 @@ import { apiFetch } from "@renderer/queries/api-fetch"
import { feedActions, useFeedStore } from "@renderer/store"
import { useMutation } from "@tanstack/react-query"
import { useHover } from "@use-gesture/react"
import { useRef } from "react"
import { useEffect, useRef, useState } from "react"
export function EntryItemWrapper({
entry,
children,
view,
hoverToRead,
}: {
entry: EntriesResponse[number] | EntryResponse
children: React.ReactNode
view?: number
hoverToRead: boolean
}) {
const { items } = useEntryActions({
view,
@ -46,16 +48,24 @@ export function EntryItemWrapper({
})
const itemRef = useRef<HTMLDivElement>(null)
const [hovered, setHovered] = useState(false)
useHover(
(state) => {
if (state.active && !entry.read) {
if (hoverToRead && state.active) {
read.mutate()
}
setHovered(state.active)
},
{
target: itemRef,
enabled: !entry.read,
},
)
useEffect(() => {
if (hoverToRead && hovered) {
read.mutate()
}
}, [hoverToRead, hovered, read])
if (!entry?.entries.url || view === undefined) return children