1
- import Link from 'next/link'
2
- import { useRouter } from 'next/router'
3
- import { useEffect , useState , useRef , useLayoutEffect } from 'react'
4
- import { useGlobal } from '@/lib/global'
5
- import { saveDarkModeToLocalStorage , THEMES } from '@/themes/theme'
6
1
import useWindowSize from '@/hooks/useWindowSize'
7
2
import { siteConfig } from '@/lib/config'
3
+ import { useGlobal } from '@/lib/global'
4
+ import { THEMES , saveDarkModeToLocalStorage } from '@/themes/theme'
5
+ import Link from 'next/link'
6
+ import { useRouter } from 'next/router'
7
+ import { useEffect , useLayoutEffect , useRef , useState } from 'react'
8
8
9
9
/**
10
10
* 自定义右键菜单
@@ -20,14 +20,14 @@ export default function CustomContextMenu(props) {
20
20
const [ width , setWidth ] = useState ( 0 )
21
21
const [ height , setHeight ] = useState ( 0 )
22
22
23
- const { latestPosts } = props
23
+ const { allNavPages } = props
24
24
const router = useRouter ( )
25
25
/**
26
26
* 随机跳转文章
27
27
*/
28
28
function handleJumpToRandomPost ( ) {
29
- const randomIndex = Math . floor ( Math . random ( ) * latestPosts . length )
30
- const randomPost = latestPosts [ randomIndex ]
29
+ const randomIndex = Math . floor ( Math . random ( ) * allNavPages . length )
30
+ const randomPost = allNavPages [ randomIndex ]
31
31
router . push ( `${ siteConfig ( 'SUB_PATH' , '' ) } /${ randomPost ?. slug } ` )
32
32
}
33
33
@@ -37,16 +37,26 @@ export default function CustomContextMenu(props) {
37
37
} , [ ] )
38
38
39
39
useEffect ( ( ) => {
40
- const handleContextMenu = ( event ) => {
40
+ setShow ( false )
41
+ } , [ router ] )
42
+
43
+ useEffect ( ( ) => {
44
+ const handleContextMenu = event => {
41
45
event . preventDefault ( )
42
46
// 计算点击位置加菜单宽高是否超出屏幕,如果超出则贴边弹出
43
- const x = ( event . clientX < windowSize . width - width ) ? event . clientX : windowSize . width - width
44
- const y = ( event . clientY < windowSize . height - height ) ? event . clientY : windowSize . height - height
47
+ const x =
48
+ event . clientX < windowSize . width - width
49
+ ? event . clientX
50
+ : windowSize . width - width
51
+ const y =
52
+ event . clientY < windowSize . height - height
53
+ ? event . clientY
54
+ : windowSize . height - height
45
55
setPosition ( { y : `${ y } px` , x : `${ x } px` } )
46
56
setShow ( true )
47
57
}
48
58
49
- const handleClick = ( event ) => {
59
+ const handleClick = event => {
50
60
if ( menuRef . current && ! menuRef . current . contains ( event . target ) ) {
51
61
setShow ( false )
52
62
}
@@ -80,19 +90,20 @@ export default function CustomContextMenu(props) {
80
90
81
91
function handleCopyLink ( ) {
82
92
const url = window . location . href
83
- navigator . clipboard . writeText ( url )
93
+ navigator . clipboard
94
+ . writeText ( url )
84
95
. then ( ( ) => {
85
96
console . log ( '页面地址已复制' )
86
97
} )
87
- . catch ( ( error ) => {
98
+ . catch ( error => {
88
99
console . error ( '复制页面地址失败:' , error )
89
100
} )
90
101
setShow ( false )
91
102
}
92
103
93
104
/**
94
- * 切换主题
95
- */
105
+ * 切换主题
106
+ */
96
107
function handleChangeTheme ( ) {
97
108
const randomTheme = THEMES [ Math . floor ( Math . random ( ) * THEMES . length ) ] // 从THEMES数组中 随机取一个主题
98
109
const query = router . query
@@ -104,14 +115,14 @@ export default function CustomContextMenu(props) {
104
115
* 复制内容
105
116
*/
106
117
function handleCopy ( ) {
107
- const selectedText = document . getSelection ( ) . toString ( ) ;
118
+ const selectedText = document . getSelection ( ) . toString ( )
108
119
if ( selectedText ) {
109
- const tempInput = document . createElement ( 'input' ) ;
110
- tempInput . value = selectedText ;
111
- document . body . appendChild ( tempInput ) ;
112
- tempInput . select ( ) ;
113
- document . execCommand ( 'copy' ) ;
114
- document . body . removeChild ( tempInput ) ;
120
+ const tempInput = document . createElement ( 'input' )
121
+ tempInput . value = selectedText
122
+ document . body . appendChild ( tempInput )
123
+ tempInput . select ( )
124
+ document . execCommand ( 'copy' )
125
+ document . body . removeChild ( tempInput )
115
126
// alert("Text copied: " + selectedText);
116
127
} else {
117
128
// alert("Please select some text first.");
@@ -130,76 +141,119 @@ export default function CustomContextMenu(props) {
130
141
}
131
142
132
143
return (
133
- < div
134
- ref = { menuRef }
135
- style = { { top : position . y , left : position . x } }
136
- className = { `${ show ? '' : 'invisible opacity-0' } select-none transition-opacity duration-200 fixed z-50` }
137
- >
138
-
139
- { /* 菜单内容 */ }
140
- < div className = 'rounded-xl w-52 dark:hover:border-yellow-600 bg-white dark:bg-[#040404] dark:text-gray-200 dark:border-gray-600 p-3 border drop-shadow-lg flex-col duration-300 transition-colors' >
141
- { /* 顶部导航按钮 */ }
142
- < div className = 'flex justify-between' >
143
- < i onClick = { handleBack } className = "hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-left" > </ i >
144
- < i onClick = { handleForward } className = "hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-right" > </ i >
145
- < i onClick = { handleRefresh } className = "hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-rotate-right" > </ i >
146
- < i onClick = { handleScrollTop } className = "hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-up" > </ i >
147
- </ div >
148
-
149
- < hr className = 'my-2 border-dashed' />
150
-
151
- { /* 跳转导航按钮 */ }
152
- < div className = 'w-full px-2' >
153
-
154
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST' ) && < div onClick = { handleJumpToRandomPost } title = { locale . MENU . WALK_AROUND } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
155
- < i className = "fa-solid fa-podcast mr-2" />
156
- < div className = 'whitespace-nowrap' > { locale . MENU . WALK_AROUND } </ div >
157
- </ div > }
158
-
159
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY' ) && < Link href = '/category' title = { locale . MENU . CATEGORY } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
160
- < i className = "fa-solid fa-square-minus mr-2" />
161
- < div className = 'whitespace-nowrap' > { locale . MENU . CATEGORY } </ div >
162
- </ Link > }
163
-
164
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG' ) && < Link href = '/tag' title = { locale . MENU . TAGS } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
165
- < i className = "fa-solid fa-tag mr-2" />
166
- < div className = 'whitespace-nowrap' > { locale . MENU . TAGS } </ div >
167
- </ Link > }
168
-
169
- </ div >
170
-
171
- < hr className = 'my-2 border-dashed' />
172
-
173
- { /* 功能按钮 */ }
174
- < div className = 'w-full px-2' >
175
-
176
- { siteConfig ( 'CAN_COPY' ) && (
177
- < div onClick = { handleCopy } title = { locale . MENU . COPY } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
178
- < i className = "fa-solid fa-copy mr-2" />
179
- < div className = 'whitespace-nowrap' > { locale . MENU . COPY } </ div >
180
- </ div >
181
- ) }
182
-
183
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK' ) && < div onClick = { handleCopyLink } title = { locale . MENU . SHARE_URL } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
184
- < i className = "fa-solid fa-arrow-up-right-from-square mr-2" />
185
- < div className = 'whitespace-nowrap' > { locale . MENU . SHARE_URL } </ div >
186
- </ div > }
187
-
188
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE' ) && < div onClick = { handleChangeDarkMode } title = { isDarkMode ? locale . MENU . LIGHT_MODE : locale . MENU . DARK_MODE } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
189
- { isDarkMode ? < i className = "fa-regular fa-sun mr-2" /> : < i className = "fa-regular fa-moon mr-2" /> }
190
- < div className = 'whitespace-nowrap' > { isDarkMode ? locale . MENU . LIGHT_MODE : locale . MENU . DARK_MODE } </ div >
191
- </ div > }
192
-
193
- { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH' ) && (
194
- < div onClick = { handleChangeTheme } title = { locale . MENU . THEME_SWITCH } className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
195
- < i className = "fa-solid fa-palette mr-2" />
196
- < div className = 'whitespace-nowrap' > { locale . MENU . THEME_SWITCH } </ div >
197
- </ div >
198
- ) }
199
-
200
- </ div >
201
-
144
+ < div
145
+ ref = { menuRef }
146
+ style = { { top : position . y , left : position . x } }
147
+ className = { `${ show ? '' : 'invisible opacity-0' } select-none transition-opacity duration-200 fixed z-50` } >
148
+ { /* 菜单内容 */ }
149
+ < div className = 'rounded-xl w-52 dark:hover:border-yellow-600 bg-white dark:bg-[#040404] dark:text-gray-200 dark:border-gray-600 p-3 border drop-shadow-lg flex-col duration-300 transition-colors' >
150
+ { /* 顶部导航按钮 */ }
151
+ < div className = 'flex justify-between' >
152
+ < i
153
+ onClick = { handleBack }
154
+ className = 'hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-left' > </ i >
155
+ < i
156
+ onClick = { handleForward }
157
+ className = 'hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-right' > </ i >
158
+ < i
159
+ onClick = { handleRefresh }
160
+ className = 'hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-rotate-right' > </ i >
161
+ < i
162
+ onClick = { handleScrollTop }
163
+ className = 'hover:bg-blue-600 hover:text-white px-2 py-2 text-center w-8 rounded cursor-pointer fa-solid fa-arrow-up' > </ i >
164
+ </ div >
165
+
166
+ < hr className = 'my-2 border-dashed' />
167
+
168
+ { /* 跳转导航按钮 */ }
169
+ < div className = 'w-full px-2' >
170
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST' ) && (
171
+ < div
172
+ onClick = { handleJumpToRandomPost }
173
+ title = { locale . MENU . WALK_AROUND }
174
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
175
+ < i className = 'fa-solid fa-podcast mr-2' />
176
+ < div className = 'whitespace-nowrap' > { locale . MENU . WALK_AROUND } </ div >
177
+ </ div >
178
+ ) }
179
+
180
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY' ) && (
181
+ < Link
182
+ href = '/category'
183
+ title = { locale . MENU . CATEGORY }
184
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
185
+ < i className = 'fa-solid fa-square-minus mr-2' />
186
+ < div className = 'whitespace-nowrap' > { locale . MENU . CATEGORY } </ div >
187
+ </ Link >
188
+ ) }
189
+
190
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG' ) && (
191
+ < Link
192
+ href = '/tag'
193
+ title = { locale . MENU . TAGS }
194
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
195
+ < i className = 'fa-solid fa-tag mr-2' />
196
+ < div className = 'whitespace-nowrap' > { locale . MENU . TAGS } </ div >
197
+ </ Link >
198
+ ) }
199
+ </ div >
200
+
201
+ < hr className = 'my-2 border-dashed' />
202
+
203
+ { /* 功能按钮 */ }
204
+ < div className = 'w-full px-2' >
205
+ { siteConfig ( 'CAN_COPY' ) && (
206
+ < div
207
+ onClick = { handleCopy }
208
+ title = { locale . MENU . COPY }
209
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
210
+ < i className = 'fa-solid fa-copy mr-2' />
211
+ < div className = 'whitespace-nowrap' > { locale . MENU . COPY } </ div >
212
+ </ div >
213
+ ) }
214
+
215
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK' ) && (
216
+ < div
217
+ onClick = { handleCopyLink }
218
+ title = { locale . MENU . SHARE_URL }
219
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
220
+ < i className = 'fa-solid fa-arrow-up-right-from-square mr-2' />
221
+ < div className = 'whitespace-nowrap' > { locale . MENU . SHARE_URL } </ div >
222
+ </ div >
223
+ ) }
224
+
225
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE' ) && (
226
+ < div
227
+ onClick = { handleChangeDarkMode }
228
+ title = {
229
+ isDarkMode ? locale . MENU . LIGHT_MODE : locale . MENU . DARK_MODE
230
+ }
231
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
232
+ { isDarkMode ? (
233
+ < i className = 'fa-regular fa-sun mr-2' />
234
+ ) : (
235
+ < i className = 'fa-regular fa-moon mr-2' />
236
+ ) }
237
+ < div className = 'whitespace-nowrap' >
238
+ { ' ' }
239
+ { isDarkMode ? locale . MENU . LIGHT_MODE : locale . MENU . DARK_MODE }
240
+ </ div >
241
+ </ div >
242
+ ) }
243
+
244
+ { siteConfig ( 'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH' ) && (
245
+ < div
246
+ onClick = { handleChangeTheme }
247
+ title = { locale . MENU . THEME_SWITCH }
248
+ className = 'w-full px-2 h-10 flex justify-start items-center flex-nowrap cursor-pointer hover:bg-blue-600 hover:text-white rounded-lg duration-200 transition-all' >
249
+ < i className = 'fa-solid fa-palette mr-2' />
250
+ < div className = 'whitespace-nowrap' >
251
+ { locale . MENU . THEME_SWITCH }
252
+ </ div >
202
253
</ div >
203
- </ div >
254
+ ) }
255
+ </ div >
256
+ </ div >
257
+ </ div >
204
258
)
205
259
}
0 commit comments