Skip to content

Commit

Permalink
update:更新右键菜单的实现方式
Browse files Browse the repository at this point in the history
  • Loading branch information
nowscott committed Jul 21, 2024
1 parent c77bee9 commit 630eecb
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 110 deletions.
85 changes: 85 additions & 0 deletions components/FontMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useEffect, useRef } from 'react';
import { setCookie, getCookie } from '../utils/cookies';
import { useFont } from '../contexts/FontContext';

const fontData = {
fonts: [
{ name: 'Smiley Sans Oblique', displayName: '得意黑', class: 'font-smiley' },
{ name: 'LXGW WenKai', displayName: '霞鹜文楷', class: 'font-wenkai' },
{ name: 'KingHwa_OldSong', displayName: '京華老宋体', class: 'font-oldsong' },
{ name: 'MuzaiPixel', displayName: '目哉像素体', class: 'font-pixel' },
{ name: 'LXGW Marker Gothic', displayName: '霞鹜漫黑', class: 'font-marker' },
],
};

const FontMenu = () => {
const { selectedFont, setSelectedFont } = useFont();
const contextMenuRef = useRef(null);

useEffect(() => {
const userFontClass = getCookie('userFont');
if (userFontClass) {
document.documentElement.classList.add(userFontClass);
setSelectedFont(userFontClass);
}

const handleContextMenu = (event) => {
event.preventDefault();
if (contextMenuRef.current) {
const menuWidth = contextMenuRef.current.offsetWidth;
const menuHeight = contextMenuRef.current.offsetHeight;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const x = event.pageX + menuWidth > screenWidth ? event.pageX - menuWidth : event.pageX;
const y = event.pageY + menuHeight > screenHeight ? event.pageY - menuHeight : event.pageY;

contextMenuRef.current.style.display = 'block';
contextMenuRef.current.style.left = `${x}px`;
contextMenuRef.current.style.top = `${y}px`;
}
};

const handleClick = (event) => {
if (contextMenuRef.current && event.target.offsetParent !== contextMenuRef.current) {
contextMenuRef.current.style.display = 'none';
}
};

document.addEventListener('contextmenu', handleContextMenu);
document.addEventListener('click', handleClick);

return () => {
document.removeEventListener('contextmenu', handleContextMenu);
document.removeEventListener('click', handleClick);
};
}, []);

const changeFont = (fontClass) => {
document.documentElement.classList.remove(...fontData.fonts.map(f => f.class)); // 移除所有字体类
document.documentElement.classList.add(fontClass); // 添加新的字体类
setCookie('userFont', fontClass, 365); // 更新Cookie,持续365天
setSelectedFont(fontClass); // 更新上下文状态
if (contextMenuRef.current) {
contextMenuRef.current.style.display = 'none'; // 隐藏菜单
}
};

return (
<div ref={contextMenuRef} className="hidden absolute z-50 bg-stone-100 dark:bg-stone-800 text-stone-800 dark:text-stone-100 border border-gray-300 shadow-lg rounded-md p-0 w-32">
<ul className="list-none m-0 p-0">
{fontData.fonts.map((font) => (
<li
key={font.class}
className={`px-2 py-2 cursor-pointer white-space: nowrap ${selectedFont === font.class ? 'shadow-md bg-gray-100 dark:bg-slate-800' : ''}`}
style={{ fontFamily: font.name }}
onClick={() => changeFont(font.class)}
>
{font.displayName}
</li>
))}
</ul>
</div>
);
};

export default FontMenu;
15 changes: 15 additions & 0 deletions contexts/FontContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { createContext, useState, useContext } from 'react';

const FontContext = createContext();

export const FontProvider = ({ children }) => {
const [selectedFont, setSelectedFont] = useState('font-serif');

return (
<FontContext.Provider value={{ selectedFont, setSelectedFont }}>
{children}
</FontContext.Provider>
);
};

export const useFont = () => useContext(FontContext);
110 changes: 0 additions & 110 deletions lib/contextMenu.js

This file was deleted.

21 changes: 21 additions & 0 deletions utils/cookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// utils/cookies.js
export const setCookie = (name, value, days) => {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
};

export const getCookie = (name) => {
const nameEQ = name + '=';
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
};

0 comments on commit 630eecb

Please sign in to comment.