nnbb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.local +2 -0
  3. package/.eslintrc.json +15 -0
  4. package/.github/stale.yml +16 -0
  5. package/.github/workflows/codeql-analysis.yml +73 -0
  6. package/.github/workflows/docker-ghcr.yaml +59 -0
  7. package/.prettierrc +9 -0
  8. package/.vscode/launch.json +28 -0
  9. package/.vscode/settings.json +6 -0
  10. package/Dockerfile +38 -0
  11. package/LICENSE +21 -0
  12. package/README.md +16 -0
  13. package/blog.config.js +454 -0
  14. package/components/Ackee.js +83 -0
  15. package/components/AdBlockDetect.js +40 -0
  16. package/components/AlgoliaSearchModal.js +250 -0
  17. package/components/Artalk.js +30 -0
  18. package/components/Busuanzi.js +26 -0
  19. package/components/ChatBase.js +19 -0
  20. package/components/Collapse.tsx +134 -0
  21. package/components/Comment.js +161 -0
  22. package/components/CommonHead.tsx +101 -0
  23. package/components/CommonScript.js +125 -0
  24. package/components/CusdisComponent.js +35 -0
  25. package/components/CustomContextMenu.js +221 -0
  26. package/components/DebugPanel.js +134 -0
  27. package/components/DisableCopy.js +21 -0
  28. package/components/Draggable.js +167 -0
  29. package/components/Equation.js +31 -0
  30. package/components/ExternalPlugins.js +75 -0
  31. package/components/ExternalScript.js +29 -0
  32. package/components/FacebookMessenger.js +255 -0
  33. package/components/FacebookPage.js +34 -0
  34. package/components/Fireworks.js +210 -0
  35. package/components/FlipCard.js +56 -0
  36. package/components/FlutteringRibbon.js +322 -0
  37. package/components/FullScreenButton.js +48 -0
  38. package/components/Giscus.js +33 -0
  39. package/components/Gitalk.js +42 -0
  40. package/components/GoogleAdsense.js +111 -0
  41. package/components/Gtag.js +18 -0
  42. package/components/HeroIcons.tsx +321 -0
  43. package/components/KatexReact.js +53 -0
  44. package/components/LazyImage.js +95 -0
  45. package/components/Live2D.js +52 -0
  46. package/components/Loading.js +20 -0
  47. package/components/Mark.js +28 -0
  48. package/components/NProgress.ts +8 -0
  49. package/components/Nest.js +124 -0
  50. package/components/NotionIcon.js +20 -0
  51. package/components/NotionPage.tsx +206 -0
  52. package/components/Player.js +54 -0
  53. package/components/PrismMac.js +236 -0
  54. package/components/QrCode.js +34 -0
  55. package/components/Ribbon.js +98 -0
  56. package/components/Sakura.js +192 -0
  57. package/components/Select.js +40 -0
  58. package/components/ShareBar.js +29 -0
  59. package/components/ShareButtons.js +403 -0
  60. package/components/SideBarDrawer.js +50 -0
  61. package/components/StarrySky.js +130 -0
  62. package/components/Tabs.js +64 -0
  63. package/components/ThemeSwitch.js +67 -0
  64. package/components/Twikoo.js +27 -0
  65. package/components/TwikooCommentCount.js +22 -0
  66. package/components/TwikooCommentCounter.js +78 -0
  67. package/components/TwikooRecentComments.js +11 -0
  68. package/components/Utterances.js +35 -0
  69. package/components/VConsole.js +76 -0
  70. package/components/ValineComponent.js +59 -0
  71. package/components/ValineCount.js +6 -0
  72. package/components/ValinePanel.js +3 -0
  73. package/components/Vercel.tsx +54 -0
  74. package/components/WWAds.js +18 -0
  75. package/components/WalineComponent.js +83 -0
  76. package/components/WebMention.js +173 -0
  77. package/components/Webwhiz.js +17 -0
  78. package/components/WordCount.js +73 -0
  79. package/hooks/useToggleClickOutSide.ts +32 -0
  80. package/hooks/useWindowSize.ts +30 -0
  81. package/lib/algolia.js +108 -0
  82. package/lib/busuanzi.js +99 -0
  83. package/lib/cache/cacheManager.ts +49 -0
  84. package/lib/cache/localFileCache.ts +56 -0
  85. package/lib/cache/memoryMache.ts +20 -0
  86. package/lib/cache/mongoDbCache.ts +70 -0
  87. package/lib/cache/types.ts +5 -0
  88. package/lib/font.js +46 -0
  89. package/lib/global.tsx +129 -0
  90. package/lib/gtag.js +17 -0
  91. package/lib/mailchimp.js +49 -0
  92. package/lib/memorize.js +0 -0
  93. package/lib/mhchem.js +1696 -0
  94. package/lib/notion/getAllCategories.ts +51 -0
  95. package/lib/notion/getAllPageIds.ts +51 -0
  96. package/lib/notion/getAllPosts.js +68 -0
  97. package/lib/notion/getAllTags.ts +43 -0
  98. package/lib/notion/getNotionData.ts +340 -0
  99. package/lib/notion/getPageInfoOfPostPage.ts +58 -0
  100. package/lib/notion/getPageProperties.ts +203 -0
  101. package/lib/notion/getPageTableOfContents.ts +107 -0
  102. package/lib/notion/getPostBlocks.ts +147 -0
  103. package/lib/notion/mapImage.ts +130 -0
  104. package/lib/notion/types.ts +125 -0
  105. package/lib/notion.js +2 -0
  106. package/lib/robots.txt.js +25 -0
  107. package/lib/rss.js +63 -0
  108. package/lib/sitemap.xml.js +67 -0
  109. package/lib/utils.js +212 -0
  110. package/next-env.d.ts +5 -0
  111. package/next-i18next.config.js +7 -0
  112. package/next-sitemap.config.js +11 -0
  113. package/next.config.js +124 -0
  114. package/package.json +92 -0
  115. package/pages/404.tsx +40 -0
  116. package/pages/[prefix]/[slug].tsx +123 -0
  117. package/pages/[prefix]/index.tsx +223 -0
  118. package/pages/_app.js +59 -0
  119. package/pages/_document.js +42 -0
  120. package/pages/api/subscribe.js +22 -0
  121. package/pages/archive/index.tsx +79 -0
  122. package/pages/category/[category]/index.tsx +87 -0
  123. package/pages/category/[category]/page/[page].tsx +103 -0
  124. package/pages/category/index.tsx +43 -0
  125. package/pages/index.tsx +88 -0
  126. package/pages/page/[page].tsx +93 -0
  127. package/pages/search/[keyword]/index.tsx +162 -0
  128. package/pages/search/[keyword]/page/[page].tsx +166 -0
  129. package/pages/search/index.tsx +69 -0
  130. package/pages/sitemap.xml.js +70 -0
  131. package/pages/tag/[tag]/index.tsx +73 -0
  132. package/pages/tag/[tag]/page/[page].tsx +87 -0
  133. package/pages/tag/index.tsx +42 -0
  134. package/postcss.config.js +6 -0
  135. package/public/ads.txt +1 -0
  136. package/public/avatar.png +0 -0
  137. package/public/avatar.svg +11 -0
  138. package/public/bg_image.jpg +0 -0
  139. package/public/css/all.min.css +9 -0
  140. package/public/css/custom.css +8 -0
  141. package/public/css/img-shadow.css +5 -0
  142. package/public/css/prism-mac-style.css +58 -0
  143. package/public/favicon.ico +0 -0
  144. package/public/favicon.svg +9 -0
  145. package/public/js/cusdis.es.js +107 -0
  146. package/public/js/custom.js +1 -0
  147. package/public/locales/en/common.json +44 -0
  148. package/public/locales/en/menu.json +9 -0
  149. package/public/locales/en/nav.json +11 -0
  150. package/public/locales/zh-CN/common.json +44 -0
  151. package/public/locales/zh-CN/menu.json +9 -0
  152. package/public/locales/zh-CN/nav.json +9 -0
  153. package/public/webfonts/fa-brands-400.ttf +0 -0
  154. package/public/webfonts/fa-brands-400.woff2 +0 -0
  155. package/public/webfonts/fa-regular-400.ttf +0 -0
  156. package/public/webfonts/fa-regular-400.woff2 +0 -0
  157. package/public/webfonts/fa-solid-900.ttf +0 -0
  158. package/public/webfonts/fa-solid-900.woff2 +0 -0
  159. package/public/webfonts/fa-v4compatibility.ttf +0 -0
  160. package/public/webfonts/fa-v4compatibility.woff2 +0 -0
  161. package/styles/animate.css +503 -0
  162. package/styles/globals.css +183 -0
  163. package/styles/notion.css +2064 -0
  164. package/styles/nprogress.css +84 -0
  165. package/styles/prism-theme.css +119 -0
  166. package/styles/utility-patterns.css +79 -0
  167. package/tailwind.config.js +37 -0
  168. package/theme/index.ts +6 -0
  169. package/theme/types/@theme-components.d.ts +29 -0
  170. package/theme/useLayout.ts +41 -0
  171. package/theme/utils.ts +108 -0
  172. package/themes/innocent/package.json +7 -0
  173. package/themes/innocent/theme.config.js +1 -0
  174. package/themes/nobelium/components/Announcement.tsx +27 -0
  175. package/themes/nobelium/components/ArticleFooter.tsx +39 -0
  176. package/themes/nobelium/components/ArticleInfo.tsx +58 -0
  177. package/themes/nobelium/components/ArticleLock.tsx +86 -0
  178. package/themes/nobelium/components/BlogArchiveItem.js +41 -0
  179. package/themes/nobelium/components/BlogListBar.js +39 -0
  180. package/themes/nobelium/components/BlogListPage.tsx +67 -0
  181. package/themes/nobelium/components/BlogListScroll.tsx +96 -0
  182. package/themes/nobelium/components/BlogPost.tsx +33 -0
  183. package/themes/nobelium/components/DarkModeButton.tsx +50 -0
  184. package/themes/nobelium/components/ExampleRecentComments.js +35 -0
  185. package/themes/nobelium/components/Footer.tsx +35 -0
  186. package/themes/nobelium/components/JumpToTopButton.tsx +39 -0
  187. package/themes/nobelium/components/LanguageSwitchButton.tsx +58 -0
  188. package/themes/nobelium/components/MenuItemCollapse.tsx +92 -0
  189. package/themes/nobelium/components/MenuItemDrop.tsx +83 -0
  190. package/themes/nobelium/components/Nav/Nav.module.css +50 -0
  191. package/themes/nobelium/components/Nav/Nav.tsx +187 -0
  192. package/themes/nobelium/components/RandomPostButton.tsx +31 -0
  193. package/themes/nobelium/components/SearchButton.tsx +31 -0
  194. package/themes/nobelium/components/SearchInput.tsx +94 -0
  195. package/themes/nobelium/components/SearchNavBar.js +19 -0
  196. package/themes/nobelium/components/SideBar.js +83 -0
  197. package/themes/nobelium/components/SvgIcon.js +29 -0
  198. package/themes/nobelium/components/TagItem.js +13 -0
  199. package/themes/nobelium/components/Tags.tsx +44 -0
  200. package/themes/nobelium/components/Title.js +19 -0
  201. package/themes/nobelium/index.tsx +28 -0
  202. package/themes/nobelium/layout/LayoutBase.tsx +79 -0
  203. package/themes/nobelium/pages/Archive.tsx +30 -0
  204. package/themes/nobelium/pages/Category.tsx +43 -0
  205. package/themes/nobelium/pages/Home.tsx +22 -0
  206. package/themes/nobelium/pages/PageNotFound.tsx +15 -0
  207. package/themes/nobelium/pages/Post.tsx +34 -0
  208. package/themes/nobelium/pages/PostList.tsx +74 -0
  209. package/themes/nobelium/pages/Search.tsx +65 -0
  210. package/themes/nobelium/pages/Tag.tsx +42 -0
  211. package/themes/nobelium/providers/index.tsx +60 -0
  212. package/themes/nobelium/stores/index.tsx +42 -0
  213. package/themes/nobelium/theme.config.ts +17 -0
  214. package/themes/nobelium/types/index.ts +10 -0
  215. package/tsconfig.json +29 -0
  216. package/types/index.ts +1 -0
  217. package/types/page.ts +102 -0
  218. package/vercel.json +5 -0
@@ -0,0 +1,403 @@
1
+ import BLOG from '@/blog.config';
2
+ import copy from 'copy-to-clipboard';
3
+ import dynamic from 'next/dynamic';
4
+ import { useState } from 'react';
5
+
6
+ import {
7
+ FacebookShareButton,
8
+ FacebookIcon,
9
+ FacebookMessengerShareButton,
10
+ FacebookMessengerIcon,
11
+ RedditShareButton,
12
+ RedditIcon,
13
+ LineShareButton,
14
+ LineIcon,
15
+ EmailShareButton,
16
+ EmailIcon,
17
+ TwitterShareButton,
18
+ TwitterIcon,
19
+ TelegramShareButton,
20
+ TelegramIcon,
21
+ WhatsappShareButton,
22
+ WhatsappIcon,
23
+ LinkedinShareButton,
24
+ LinkedinIcon,
25
+ PinterestShareButton,
26
+ PinterestIcon,
27
+ VKIcon,
28
+ VKShareButton,
29
+ OKShareButton,
30
+ OKIcon,
31
+ TumblrShareButton,
32
+ TumblrIcon,
33
+ LivejournalIcon,
34
+ LivejournalShareButton,
35
+ MailruShareButton,
36
+ MailruIcon,
37
+ ViberIcon,
38
+ ViberShareButton,
39
+ WorkplaceShareButton,
40
+ WorkplaceIcon,
41
+ WeiboShareButton,
42
+ WeiboIcon,
43
+ PocketShareButton,
44
+ PocketIcon,
45
+ InstapaperShareButton,
46
+ InstapaperIcon,
47
+ HatenaShareButton,
48
+ HatenaIcon,
49
+ } from 'react-share';
50
+ import { useTranslation } from 'next-i18next';
51
+
52
+ const QrCode = dynamic(() => import('@/components/QrCode'), { ssr: false });
53
+
54
+ /**
55
+ * @author https://github.com/txs
56
+ * @param {*} param0
57
+ * @returns
58
+ */
59
+ const ShareButtons = ({ shareUrl, title, body, image }) => {
60
+ const services = BLOG.POSTS_SHARE_SERVICES.split(',');
61
+ const titleWithSiteInfo = title + ' | ' + BLOG.TITLE;
62
+ const [qrCodeShow, setQrCodeShow] = useState(false);
63
+ const { t } = useTranslation('common');
64
+
65
+ const copyUrl = () => {
66
+ copy(shareUrl);
67
+ alert(t('url-copied'));
68
+ };
69
+
70
+ const openPopover = () => {
71
+ setQrCodeShow(true);
72
+ };
73
+ const closePopover = () => {
74
+ setQrCodeShow(false);
75
+ };
76
+
77
+ return (
78
+ <>
79
+ {services.map((singleService) => {
80
+ if (singleService === 'facebook') {
81
+ return (
82
+ <FacebookShareButton
83
+ key={singleService}
84
+ url={shareUrl}
85
+ className="mx-1"
86
+ >
87
+ <FacebookIcon size={32} round />
88
+ </FacebookShareButton>
89
+ );
90
+ }
91
+ if (singleService === 'messenger') {
92
+ return (
93
+ <FacebookMessengerShareButton
94
+ key={singleService}
95
+ url={shareUrl}
96
+ appId={BLOG.FACEBOOK_APP_ID}
97
+ className="mx-1"
98
+ >
99
+ <FacebookMessengerIcon size={32} round />
100
+ </FacebookMessengerShareButton>
101
+ );
102
+ }
103
+ if (singleService === 'line') {
104
+ return (
105
+ <LineShareButton
106
+ key={singleService}
107
+ url={shareUrl}
108
+ className="mx-1"
109
+ >
110
+ <LineIcon size={32} round />
111
+ </LineShareButton>
112
+ );
113
+ }
114
+ if (singleService === 'reddit') {
115
+ return (
116
+ <RedditShareButton
117
+ key={singleService}
118
+ url={shareUrl}
119
+ title={titleWithSiteInfo}
120
+ windowWidth={660}
121
+ windowHeight={460}
122
+ className="mx-1"
123
+ >
124
+ <RedditIcon size={32} round />
125
+ </RedditShareButton>
126
+ );
127
+ }
128
+ if (singleService === 'email') {
129
+ return (
130
+ <EmailShareButton
131
+ key={singleService}
132
+ url={shareUrl}
133
+ subject={titleWithSiteInfo}
134
+ body={body}
135
+ className="mx-1"
136
+ >
137
+ <EmailIcon size={32} round />
138
+ </EmailShareButton>
139
+ );
140
+ }
141
+ if (singleService === 'twitter') {
142
+ return (
143
+ <TwitterShareButton
144
+ key={singleService}
145
+ url={shareUrl}
146
+ title={titleWithSiteInfo}
147
+ className="mx-1"
148
+ >
149
+ <TwitterIcon size={32} round />
150
+ </TwitterShareButton>
151
+ );
152
+ }
153
+ if (singleService === 'telegram') {
154
+ return (
155
+ <TelegramShareButton
156
+ key={singleService}
157
+ url={shareUrl}
158
+ title={titleWithSiteInfo}
159
+ className="mx-1"
160
+ >
161
+ <TelegramIcon size={32} round />
162
+ </TelegramShareButton>
163
+ );
164
+ }
165
+ if (singleService === 'whatsapp') {
166
+ return (
167
+ <WhatsappShareButton
168
+ key={singleService}
169
+ url={shareUrl}
170
+ title={titleWithSiteInfo}
171
+ separator=":: "
172
+ className="mx-1"
173
+ >
174
+ <WhatsappIcon size={32} round />
175
+ </WhatsappShareButton>
176
+ );
177
+ }
178
+ if (singleService === 'linkedin') {
179
+ return (
180
+ <LinkedinShareButton
181
+ key={singleService}
182
+ url={shareUrl}
183
+ className="mx-1"
184
+ >
185
+ <LinkedinIcon size={32} round />
186
+ </LinkedinShareButton>
187
+ );
188
+ }
189
+ if (singleService === 'pinterest') {
190
+ return (
191
+ <PinterestShareButton
192
+ key={singleService}
193
+ url={shareUrl}
194
+ media={image}
195
+ className="mx-1"
196
+ >
197
+ <PinterestIcon size={32} round />
198
+ </PinterestShareButton>
199
+ );
200
+ }
201
+ if (singleService === 'vkshare') {
202
+ return (
203
+ <VKShareButton
204
+ key={singleService}
205
+ url={shareUrl}
206
+ image={image}
207
+ className="mx-1"
208
+ >
209
+ <VKIcon size={32} round />
210
+ </VKShareButton>
211
+ );
212
+ }
213
+ if (singleService === 'okshare') {
214
+ return (
215
+ <OKShareButton
216
+ key={singleService}
217
+ url={shareUrl}
218
+ image={image}
219
+ className="mx-1"
220
+ >
221
+ <OKIcon size={32} round />
222
+ </OKShareButton>
223
+ );
224
+ }
225
+ if (singleService === 'tumblr') {
226
+ return (
227
+ <TumblrShareButton
228
+ key={singleService}
229
+ url={shareUrl}
230
+ title={titleWithSiteInfo}
231
+ className="mx-1"
232
+ >
233
+ <TumblrIcon size={32} round />
234
+ </TumblrShareButton>
235
+ );
236
+ }
237
+ if (singleService === 'livejournal') {
238
+ return (
239
+ <LivejournalShareButton
240
+ key={singleService}
241
+ url={shareUrl}
242
+ title={titleWithSiteInfo}
243
+ description={shareUrl}
244
+ className="mx-1"
245
+ >
246
+ <LivejournalIcon size={32} round />
247
+ </LivejournalShareButton>
248
+ );
249
+ }
250
+ if (singleService === 'mailru') {
251
+ return (
252
+ <MailruShareButton
253
+ key={singleService}
254
+ url={shareUrl}
255
+ title={titleWithSiteInfo}
256
+ className="mx-1"
257
+ >
258
+ <MailruIcon size={32} round />
259
+ </MailruShareButton>
260
+ );
261
+ }
262
+ if (singleService === 'viber') {
263
+ return (
264
+ <ViberShareButton
265
+ key={singleService}
266
+ url={shareUrl}
267
+ title={titleWithSiteInfo}
268
+ className="mx-1"
269
+ >
270
+ <ViberIcon size={32} round />
271
+ </ViberShareButton>
272
+ );
273
+ }
274
+ if (singleService === 'workplace') {
275
+ return (
276
+ <WorkplaceShareButton
277
+ key={singleService}
278
+ url={shareUrl}
279
+ quote={titleWithSiteInfo}
280
+ className="mx-1"
281
+ >
282
+ <WorkplaceIcon size={32} round />
283
+ </WorkplaceShareButton>
284
+ );
285
+ }
286
+ if (singleService === 'weibo') {
287
+ return (
288
+ <WeiboShareButton
289
+ key={singleService}
290
+ url={shareUrl}
291
+ title={titleWithSiteInfo}
292
+ image={image}
293
+ className="mx-1"
294
+ >
295
+ <WeiboIcon size={32} round />
296
+ </WeiboShareButton>
297
+ );
298
+ }
299
+ if (singleService === 'pocket') {
300
+ return (
301
+ <PocketShareButton
302
+ key={singleService}
303
+ url={shareUrl}
304
+ title={titleWithSiteInfo}
305
+ className="mx-1"
306
+ >
307
+ <PocketIcon size={32} round />
308
+ </PocketShareButton>
309
+ );
310
+ }
311
+ if (singleService === 'instapaper') {
312
+ return (
313
+ <InstapaperShareButton
314
+ key={singleService}
315
+ url={shareUrl}
316
+ title={titleWithSiteInfo}
317
+ className="mx-1"
318
+ >
319
+ <InstapaperIcon size={32} round />
320
+ </InstapaperShareButton>
321
+ );
322
+ }
323
+ if (singleService === 'hatena') {
324
+ return (
325
+ <HatenaShareButton
326
+ key={singleService}
327
+ url={shareUrl}
328
+ title={titleWithSiteInfo}
329
+ windowWidth={660}
330
+ windowHeight={460}
331
+ className="mx-1"
332
+ >
333
+ <HatenaIcon size={32} round />
334
+ </HatenaShareButton>
335
+ );
336
+ }
337
+ if (singleService === 'qq') {
338
+ return (
339
+ <button
340
+ key={singleService}
341
+ className="mx-1 cursor-pointer rounded-full bg-blue-600 text-white"
342
+ >
343
+ <a
344
+ target="_blank"
345
+ rel="noreferrer"
346
+ href={`http://connect.qq.com/widget/shareqq/index.html?url=${shareUrl}&sharesource=qzone&title=${title}&desc=${body}`}
347
+ >
348
+ <i className="fab fa-qq w-8" />
349
+ </a>
350
+ </button>
351
+ );
352
+ }
353
+ if (singleService === 'wechat') {
354
+ return (
355
+ <button
356
+ onMouseEnter={openPopover}
357
+ onMouseLeave={closePopover}
358
+ aria-label={singleService}
359
+ key={singleService}
360
+ className="mx-1 cursor-pointer rounded-full bg-green-600 text-white"
361
+ >
362
+ <div id="wechat-button">
363
+ <i className="fab fa-weixin w-8" />
364
+ </div>
365
+ <div className="absolute">
366
+ <div
367
+ id="pop"
368
+ className={
369
+ (qrCodeShow ? 'opacity-100 ' : ' invisible opacity-0') +
370
+ ' absolute -left-10 bottom-10 z-40 bg-white text-center shadow-xl transition-all duration-200'
371
+ }
372
+ >
373
+ <div className="mt-1 h-28 w-28 p-2">
374
+ <QrCode value={shareUrl} />
375
+ </div>
376
+ <span className="mx-auto mb-1 rounded-t-lg p-1 text-sm font-semibold text-black">
377
+ {t('scan-qr-code')}
378
+ </span>
379
+ </div>
380
+ </div>
381
+ </button>
382
+ );
383
+ }
384
+ if (singleService === 'link') {
385
+ return (
386
+ <button
387
+ aria-label={singleService}
388
+ key={singleService}
389
+ className="mx-1 cursor-pointer rounded-full bg-yellow-500 text-white"
390
+ >
391
+ <div alt={t('url-copied')} onClick={copyUrl}>
392
+ <i className="fas fa-link w-8" />
393
+ </div>
394
+ </button>
395
+ );
396
+ }
397
+ return <></>;
398
+ })}
399
+ </>
400
+ );
401
+ };
402
+
403
+ export default ShareButtons;
@@ -0,0 +1,50 @@
1
+ import { useRouter } from 'next/router'
2
+ import { useEffect } from 'react'
3
+
4
+ /**
5
+ * 侧边栏抽屉面板,可以从侧面拉出
6
+ * @returns {JSX.Element}
7
+ * @constructor
8
+ */
9
+ const SideBarDrawer = ({ children, isOpen, onOpen, onClose, className }) => {
10
+ const router = useRouter()
11
+ useEffect(() => {
12
+ const sideBarDrawerRouteListener = () => {
13
+ switchSideDrawerVisible(false)
14
+ }
15
+ router.events.on('routeChangeComplete', sideBarDrawerRouteListener)
16
+ return () => {
17
+ router.events.off('routeChangeComplete', sideBarDrawerRouteListener)
18
+ }
19
+ }, [router.events])
20
+
21
+ // 点击按钮更改侧边抽屉状态
22
+ const switchSideDrawerVisible = (showStatus) => {
23
+ if (showStatus) {
24
+ onOpen && onOpen()
25
+ } else {
26
+ onClose && onClose()
27
+ }
28
+ const sideBarDrawer = window.document.getElementById('sidebar-drawer')
29
+ const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
30
+
31
+ if (showStatus) {
32
+ sideBarDrawer?.classList.replace('-ml-60', 'ml-0')
33
+ sideBarDrawerBackground?.classList.replace('hidden', 'block')
34
+ } else {
35
+ sideBarDrawer?.classList.replace('ml-0', '-ml-60')
36
+ sideBarDrawerBackground?.classList.replace('block', 'hidden')
37
+ }
38
+ }
39
+
40
+ return <div id='sidebar-wrapper' className={' block lg:hidden top-0 ' + className }>
41
+ <div id="sidebar-drawer" className={`${isOpen ? 'ml-0 w-60 visible' : '-ml-60 max-w-side invisible'} bg-white dark:bg-gray-900 shadow-black shadow-lg flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-30`}>
42
+ {children}
43
+ </div>
44
+
45
+ {/* 背景蒙版 */}
46
+ <div id='sidebar-drawer-background' onClick={() => { switchSideDrawerVisible(false) }}
47
+ className={`${isOpen ? 'block' : 'hidden'} animate__animated animate__fadeIn fixed top-0 duration-300 left-0 z-20 w-full h-full bg-black/70`}/>
48
+ </div>
49
+ }
50
+ export default SideBarDrawer
@@ -0,0 +1,130 @@
1
+ /* eslint-disable */
2
+ import React from 'react'
3
+
4
+ const StarrySky = () => {
5
+ React.useEffect(() => {
6
+ dark()
7
+ }, [])
8
+ return (
9
+ <div className="relative">
10
+ <canvas id="starry-sky-vixcity" style={{zIndex:1}} className="top-0 fixed pointer-events-none"></canvas>
11
+ </div>
12
+ )
13
+ }
14
+
15
+ export default StarrySky
16
+ /**
17
+ * 创建星空雨
18
+ * @param config
19
+ */
20
+ function dark() {
21
+ window.requestAnimationFrame =
22
+ window.requestAnimationFrame ||
23
+ window.mozRequestAnimationFrame ||
24
+ window.webkitRequestAnimationFrame ||
25
+ window.msRequestAnimationFrame
26
+ var n,
27
+ e,
28
+ i,
29
+ h,
30
+ t = 0.05,
31
+ s = document.getElementById('starry-sky-vixcity'),
32
+ o = !0,
33
+ a = '180,184,240',
34
+ r = '226,225,142',
35
+ d = '226,225,224',
36
+ c = []
37
+ function f() {
38
+ ;(n = window.innerWidth),
39
+ (e = window.innerHeight),
40
+ (i = 0.216 * n),
41
+ s.setAttribute('width', n),
42
+ s.setAttribute('height', e)
43
+ }
44
+ function u() {
45
+ h.clearRect(0, 0, n, e)
46
+ for (var t = c.length, i = 0; i < t; i++) {
47
+ var s = c[i]
48
+ s.move(), s.fadeIn(), s.fadeOut(), s.draw()
49
+ }
50
+ }
51
+ function y() {
52
+ ;(this.reset = function () {
53
+ ;(this.giant = m(3)),
54
+ (this.comet = !this.giant && !o && m(10)),
55
+ (this.x = l(0, n - 10)),
56
+ (this.y = l(0, e)),
57
+ (this.r = l(1.1, 2.6)),
58
+ (this.dx = l(t, 6 * t) + (this.comet + 1 - 1) * t * l(50, 120) + 2 * t),
59
+ (this.dy = -l(t, 6 * t) - (this.comet + 1 - 1) * t * l(50, 120)),
60
+ (this.fadingOut = null),
61
+ (this.fadingIn = !0),
62
+ (this.opacity = 0),
63
+ (this.opacityTresh = l(0.2, 1 - 0.4 * (this.comet + 1 - 1))),
64
+ (this.do = l(5e-4, 0.002) + 0.001 * (this.comet + 1 - 1))
65
+ }),
66
+ (this.fadeIn = function () {
67
+ this.fadingIn &&
68
+ ((this.fadingIn = !(this.opacity > this.opacityTresh)),
69
+ (this.opacity += this.do))
70
+ }),
71
+ (this.fadeOut = function () {
72
+ this.fadingOut &&
73
+ ((this.fadingOut = !(this.opacity < 0)),
74
+ (this.opacity -= this.do / 2),
75
+ (this.x > n || this.y < 0) && ((this.fadingOut = !1), this.reset()))
76
+ }),
77
+ (this.draw = function () {
78
+ if ((h.beginPath(), this.giant))
79
+ (h.fillStyle = 'rgba(' + a + ',' + this.opacity + ')'),
80
+ h.arc(this.x, this.y, 2, 0, 2 * Math.PI, !1)
81
+ else if (this.comet) {
82
+ ;(h.fillStyle = 'rgba(' + d + ',' + this.opacity + ')'),
83
+ h.arc(this.x, this.y, 1.5, 0, 2 * Math.PI, !1)
84
+ for (var t = 0; t < 30; t++)
85
+ (h.fillStyle =
86
+ 'rgba(' +
87
+ d +
88
+ ',' +
89
+ (this.opacity - (this.opacity / 20) * t) +
90
+ ')'),
91
+ h.rect(
92
+ this.x - (this.dx / 4) * t,
93
+ this.y - (this.dy / 4) * t - 2,
94
+ 2,
95
+ 2
96
+ ),
97
+ h.fill()
98
+ } else
99
+ (h.fillStyle = 'rgba(' + r + ',' + this.opacity + ')'),
100
+ h.rect(this.x, this.y, this.r, this.r)
101
+ h.closePath(), h.fill()
102
+ }),
103
+ (this.move = function () {
104
+ ;(this.x += this.dx),
105
+ (this.y += this.dy),
106
+ !1 === this.fadingOut && this.reset(),
107
+ (this.x > n - n / 4 || this.y < 0) && (this.fadingOut = !0)
108
+ }),
109
+ setTimeout(function () {
110
+ o = !1
111
+ }, 50)
112
+ }
113
+ function m(t) {
114
+ return Math.floor(1e3 * Math.random()) + 1 < 10 * t
115
+ }
116
+ function l(t, i) {
117
+ return Math.random() * (i - t) + t
118
+ }
119
+ f(),
120
+ window.addEventListener('resize', f, !1),
121
+ (function () {
122
+ h = s.getContext('2d')
123
+ for (var t = 0; t < i; t++) (c[t] = new y()), c[t].reset()
124
+ u()
125
+ })(),
126
+ (function t() {
127
+ document.getElementsByTagName('html')[0].className == 'dark' && u(),
128
+ window.requestAnimationFrame(t)
129
+ })()
130
+ }
@@ -0,0 +1,64 @@
1
+ import React, { useState } from 'react'
2
+
3
+ /**
4
+ * Tabs切换标签
5
+ * @param {*} param0
6
+ * @returns
7
+ */
8
+ const Tabs = ({ className, children }) => {
9
+ const [currentTab, setCurrentTab] = useState(0)
10
+
11
+ if (!children) {
12
+ return <></>
13
+ }
14
+
15
+ children = children.filter(c => c !== '')
16
+
17
+ let count = 0
18
+ children.forEach(e => {
19
+ if (e) {
20
+ count++
21
+ }
22
+ })
23
+
24
+ if (count === 0) {
25
+ return <></>
26
+ }
27
+
28
+ if (count === 1) {
29
+ return <section className={'duration-200 ' + className}>
30
+ {children}
31
+ </section>
32
+ }
33
+
34
+ function tabClickHandle(i) {
35
+ setCurrentTab(i)
36
+ }
37
+
38
+ return <div className={'mb-5 duration-200 ' + className}>
39
+ <ul className='flex justify-center space-x-5 pb-4 dark:text-gray-400 text-gray-600 overflow-auto'>
40
+ {children.map((item, index) => {
41
+ return <li key={index}
42
+ className={(currentTab === index ? 'font-black border-b-2 border-red-400 text-red-400 animate__animated animate__jello ' : 'font-extralight cursor-pointer') + ' text-sm font-sans '}
43
+ onClick={() => {
44
+ tabClickHandle(index)
45
+ }}>
46
+ {item?.key}
47
+ </li>
48
+ })}
49
+ </ul>
50
+ <div>
51
+ {children.map((item, index) => {
52
+ return <section key={index}
53
+ data-aos="fade-up"
54
+ data-aos-duration="300"
55
+ data-aos-once="true"
56
+ data-aos-anchor-placement="top-bottom">
57
+ {currentTab === index && item}
58
+ </section>
59
+ })}
60
+ </div>
61
+ </div>
62
+ }
63
+
64
+ export default Tabs