From 25d1f06fd50eeff49e3de9dd35ba95492463541d Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Tue, 20 May 2025 22:07:40 +0800 Subject: [PATCH] fix(desktop): reset highlightMotion state after switching entry --- .../layer/renderer/src/hooks/biz/useEntryActions.tsx | 7 ++----- .../components/src/ui/button/action-button.tsx | 4 ++++ packages/internal/utils/src/utils.spec.ts | 10 +++++++++- packages/internal/utils/src/utils.ts | 5 +++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx b/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx index b9df690a6..ec0cf1a11 100644 --- a/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx +++ b/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx @@ -1,6 +1,7 @@ import { isMobile } from "@follow/components/hooks/useMobile.js" import { FeedViewType, UserRole, views } from "@follow/constants" import { IN_ELECTRON } from "@follow/shared/constants" +import { doesTextContainHTML } from "@follow/utils/utils" import { useMemo } from "react" import { useShowAISummaryAuto, useShowAISummaryOnce } from "~/atoms/ai-summary" @@ -130,10 +131,6 @@ export class EntryActionMenuItem extends MenuItemText { } export type EntryActionItem = EntryActionMenuItem | MenuItemSeparator -function hasHTMLTags(text?: string | null): boolean { - return /<[^>]+>/.test(text || "") -} - export const useEntryActions = ({ entryId, view, @@ -158,7 +155,7 @@ export const useEntryActions = ({ const inList = !!listId const inbox = useInboxById(entry?.inboxId) const isInbox = !!inbox - const isContentContainsHTMLTags = hasHTMLTags(entry?.entries.content) + const isContentContainsHTMLTags = doesTextContainHTML(entry?.entries.content) const isShowSourceContent = useShowSourceContent() const isShowAISummaryAuto = useShowAISummaryAuto(entry) diff --git a/packages/internal/components/src/ui/button/action-button.tsx b/packages/internal/components/src/ui/button/action-button.tsx index 7ae2f4faf..061f4d1db 100644 --- a/packages/internal/components/src/ui/button/action-button.tsx +++ b/packages/internal/components/src/ui/button/action-button.tsx @@ -73,6 +73,10 @@ export const ActionButton = ({ React.useImperativeHandle(ref, () => buttonRef.current!) const [shouldHighlightMotion, setShouldHighlightMotion] = useState(highlightMotion) + React.useEffect(() => { + setShouldHighlightMotion(highlightMotion) + }, [highlightMotion]) + const [loading, setLoading] = useState(false) const Trigger = ( diff --git a/packages/internal/utils/src/utils.spec.ts b/packages/internal/utils/src/utils.spec.ts index 5baa9f7ac..18e14dbfc 100644 --- a/packages/internal/utils/src/utils.spec.ts +++ b/packages/internal/utils/src/utils.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "vitest" -import { isBizId, omitShallow, toScientificNotation } from "./utils" +import { doesTextContainHTML, isBizId, omitShallow, toScientificNotation } from "./utils" describe("utils", () => { test("isBizId", () => { @@ -85,4 +85,12 @@ describe("utils", () => { expect(omitShallow(void 0)).toEqual(void 0) expect(omitShallow([1, 2])).toEqual([1, 2]) }) + + test("does text contain html", () => { + expect(doesTextContainHTML("a
b
")).toBe(true) + expect(doesTextContainHTML("Test")).toBe(false) + expect(doesTextContainHTML("

")).toBe(false) + expect(doesTextContainHTML("Test

")).toBe(false) + expect(doesTextContainHTML("Test
")).toBe(false) + }) }) diff --git a/packages/internal/utils/src/utils.ts b/packages/internal/utils/src/utils.ts index 71b7c7726..6e87c59a2 100644 --- a/packages/internal/utils/src/utils.ts +++ b/packages/internal/utils/src/utils.ts @@ -417,3 +417,8 @@ export function combineCleanupFunctions(...fns: Array void) | vo }) } } + +export function doesTextContainHTML(text?: string | null): boolean { + if (!text) return false + return /<([a-z][a-z0-9]*)\b[^>]*>\s*[^<>\s].*<\/\1>/i.test(text) +}