diff --git a/apps/blog/src/app/[locale]/posts/[slug]/page.tsx b/apps/blog/src/app/[locale]/posts/[slug]/page.tsx index e376a2bb..c1103531 100644 --- a/apps/blog/src/app/[locale]/posts/[slug]/page.tsx +++ b/apps/blog/src/app/[locale]/posts/[slug]/page.tsx @@ -17,7 +17,7 @@ import { generateFullUrl } from '@/utils/generateFullUrl' import { memeberToPostAuthor } from '@/utils/memeberToPostAuthor' import { formatDate } from '@/utils/formatDate' import type { Language } from '@/i18n/i18n.settings' -import { ShareButton } from 'src/components/ShareButton' +import { ShareButton } from '@/components/ShareButton' import { useTranslation } from '@/i18n' interface BlogProps { @@ -95,7 +95,7 @@ export default async function Post({ params }: BlogProps) {

{formatDate(post.publishedAt, params.locale)}

diff --git a/apps/blog/src/components/ShareButton/ShareButton.tsx b/apps/blog/src/components/ShareButton/ShareButton.tsx index 0aec4323..ad3c5561 100644 --- a/apps/blog/src/components/ShareButton/ShareButton.tsx +++ b/apps/blog/src/components/ShareButton/ShareButton.tsx @@ -1,44 +1,32 @@ 'use client' -import React, { useCallback, useEffect, useRef, useState } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import * as Popover from '@radix-ui/react-popover' +import { useTimer } from '@/utils/hooks/useTimer' const popoverTimer = 1000 -export const ShareButton = ({ shareData, content }: { shareData: ShareData; content: string }) => { +export const ShareButton = ({ shareData, tooltipContent }: { shareData: ShareData; tooltipContent: string }) => { const [open, setOpen] = useState(false) - const timerIdRef = useRef(null) - const handleTimerClear = useCallback(() => { - if (timerIdRef.current) { - clearTimeout(timerIdRef.current) - timerIdRef.current = null - } - }, []) - - const handleStartTimer = useCallback(() => { - timerIdRef.current = setTimeout(() => { - setOpen(false) - handleTimerClear() - }, popoverTimer) - }, [handleTimerClear]) + const setPopoverClosed = useCallback(() => setOpen(false), [setOpen]) + const { startTimer, stopTimer } = useTimer(setPopoverClosed, popoverTimer) - const handlePopoverClick = useCallback(() => { + const handlePopoverOpen = useCallback(() => { if (open) { setOpen(false) - handleTimerClear() + stopTimer() } else { setOpen(true) - handleTimerClear() - handleStartTimer() + startTimer() } - }, [handleStartTimer, handleTimerClear, open]) + }, [startTimer, stopTimer, open]) useEffect( () => () => { - handleTimerClear() + stopTimer() }, - [handleTimerClear], + [stopTimer], ) /** @@ -53,12 +41,12 @@ export const ShareButton = ({ shareData, content }: { shareData: ShareData; cont try { if (!navigator.share) { await navigator.clipboard.writeText(shareData.url || shareData.text || shareData.title || '') - handlePopoverClick() + handlePopoverOpen() } else { await navigator.share(shareData) } } catch (error: unknown) { - handleTimerClear() + stopTimer() if (error instanceof Error && error.name === 'AbortError') { return @@ -66,10 +54,10 @@ export const ShareButton = ({ shareData, content }: { shareData: ShareData; cont console.error(error) } - }, [handlePopoverClick, handleTimerClear, shareData]) + }, [handlePopoverOpen, stopTimer, shareData]) return ( - + - {content} + {tooltipContent} diff --git a/apps/blog/src/utils/hooks/useTimer.ts b/apps/blog/src/utils/hooks/useTimer.ts new file mode 100644 index 00000000..651358c2 --- /dev/null +++ b/apps/blog/src/utils/hooks/useTimer.ts @@ -0,0 +1,28 @@ +import { useEffect, useRef, useCallback } from 'react' + +interface TimerFunctions { + startTimer: () => void + stopTimer: () => void +} + +export function useTimer(callback: () => void, delay = 2000): TimerFunctions { + const timerRef = useRef(null) + + const startTimer = useCallback(() => { + if (timerRef.current) { + clearTimeout(timerRef.current) + } + timerRef.current = setTimeout(callback, delay) + }, [callback, delay]) + + const stopTimer = useCallback(() => { + if (timerRef.current) { + clearTimeout(timerRef.current) + timerRef.current = null + } + }, []) + + useEffect(() => stopTimer, [stopTimer]) + + return { startTimer, stopTimer } +}