From 56e3df3fe5405ae501fcf868d1810453028dd892 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Thu, 30 May 2024 01:30:21 +0800 Subject: [PATCH] feat: enable hover to read after hovering list for 1 second --- .../src/components/entry-column/index.tsx | 27 +++++++++++++++++-- .../components/entry-column/item-wrapper.tsx | 14 ++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/entry-column/index.tsx b/src/renderer/src/components/entry-column/index.tsx index 52a0f42cf..067976750 100644 --- a/src/renderer/src/components/entry-column/index.tsx +++ b/src/renderer/src/components/entry-column/index.tsx @@ -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(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() { -
+
{entries.data?.pages?.map((page) => ( diff --git a/src/renderer/src/components/entry-column/item-wrapper.tsx b/src/renderer/src/components/entry-column/item-wrapper.tsx index b9836b3de..06c599402 100644 --- a/src/renderer/src/components/entry-column/item-wrapper.tsx +++ b/src/renderer/src/components/entry-column/item-wrapper.tsx @@ -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(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