import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useState, useRef, useLayoutEffect } from 'react' import { useGlobal } from '@/lib/global' import { saveDarkModeToCookies, THEMES } from '@/themes/theme' import useWindowSize from '@/hooks/useWindowSize' import { siteConfig } from '@/lib/config' /** * 自定义右键菜单 * @param {*} props * @returns */ export default function CustomContextMenu(props) { const [position, setPosition] = useState({ x: '0px', y: '0px' }) const [show, setShow] = useState(false) const { isDarkMode, updateDarkMode, locale } = useGlobal() const menuRef = useRef(null) const windowSize = useWindowSize() const [width, setWidth] = useState(0) const [height, setHeight] = useState(0) const { latestPosts } = props const router = useRouter() /** * 随机跳转文章 */ function handleJumpToRandomPost() { const randomIndex = Math.floor(Math.random() * latestPosts.length) const randomPost = latestPosts[randomIndex] router.push(`${siteConfig('SUB_PATH', '')}/${randomPost?.slug}`) } useLayoutEffect(() => { setWidth(menuRef.current.offsetWidth) setHeight(menuRef.current.offsetHeight) }, []) useEffect(() => { const handleContextMenu = (event) => { event.preventDefault() // 计算点击位置加菜单宽高是否超出屏幕,如果超出则贴边弹出 const x = (event.clientX < windowSize.width - width) ? event.clientX : windowSize.width - width const y = (event.clientY < windowSize.height - height) ? event.clientY : windowSize.height - height setPosition({ y: `${y}px`, x: `${x}px` }) setShow(true) } const handleClick = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { setShow(false) } } window.addEventListener('contextmenu', handleContextMenu) window.addEventListener('click', handleClick) return () => { window.removeEventListener('contextmenu', handleContextMenu) window.removeEventListener('click', handleClick) } }, [windowSize]) function handleBack() { window.history.back() } function handleForward() { window.history.forward() } function handleRefresh() { window.location.reload() } function handleScrollTop() { window.scrollTo({ top: 0, behavior: 'smooth' }) setShow(false) } function handleCopyLink() { const url = window.location.href navigator.clipboard.writeText(url) .then(() => { console.log('页面地址已复制') }) .catch((error) => { console.error('复制页面地址失败:', error) }) setShow(false) } /** * 切换主题 */ function handleChangeTheme() { const randomTheme = THEMES[Math.floor(Math.random() * THEMES.length)] // 从THEMES数组中 随机取一个主题 const query = router.query query.theme = randomTheme router.push({ pathname: router.pathname, query }) } /** * 复制内容 */ function handleCopy() { const selectedText = document.getSelection().toString(); if (selectedText) { const tempInput = document.createElement('input'); tempInput.value = selectedText; document.body.appendChild(tempInput); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); // alert("Text copied: " + selectedText); } else { // alert("Please select some text first."); } setShow(false) } function handleChangeDarkMode() { const newStatus = !isDarkMode saveDarkModeToCookies(newStatus) updateDarkMode(newStatus) const htmlElement = document.getElementsByTagName('html')[0] htmlElement.classList?.remove(newStatus ? 'light' : 'dark') htmlElement.classList?.add(newStatus ? 'dark' : 'light') } return (