+
diff --git a/themes/game/components/MenuList.js b/themes/game/components/MenuList.js
index 3835ee4d..16b2443f 100644
--- a/themes/game/components/MenuList.js
+++ b/themes/game/components/MenuList.js
@@ -1,30 +1,72 @@
-import Link from 'next/link'
+import { siteConfig } from '@/lib/config'
+import { useGlobal } from '@/lib/global'
import { useGameGlobal } from '..'
+import CONFIG from '../config'
+import DarkModeButton from './DarkModeButton'
+import { MenuItemDrop } from './MenuItemDrop'
-export const MenuList = () => {
+/**
+ * 导航菜单
+ */
+export const MenuList = props => {
const { setSideBarVisible } = useGameGlobal()
+ const { customNav, customMenu } = props
+ const { locale } = useGlobal()
+ const defaultLinks = [
+ {
+ id: 1,
+ icon: 'fas fa-home',
+ name: locale.NAV.INDEX,
+ to: '/' || '/',
+ show: true
+ },
+ {
+ id: 2,
+ icon: 'fas fa-th',
+ name: locale.COMMON.CATEGORY,
+ to: '/category',
+ show: siteConfig('GAME_MENU_CATEGORY', null, CONFIG)
+ },
+ {
+ id: 3,
+ icon: 'fas fa-tag',
+ name: locale.COMMON.TAGS,
+ to: '/tag',
+ show: siteConfig('GAME_MENU_TAG', null, CONFIG)
+ }
+ ]
+
+ let links = [].concat(defaultLinks)
+ if (customNav) {
+ links = defaultLinks.concat(customNav)
+ }
+
+ // 如果 开启自定义菜单,则覆盖Page生成的菜单
+ if (siteConfig('CUSTOM_MENU')) {
+ links = customMenu
+ }
+
return (
-
-
- -
-
-
-
- Home
-
-
-
- -
-
-
-
-
+
+ -
+
+
+
+
+ {links?.map(
+ (link, index) =>
+ link && link.show &&
+ )}
+
)
}
diff --git a/themes/game/components/Nav.js b/themes/game/components/Nav.js
deleted file mode 100644
index 04b1e9fb..00000000
--- a/themes/game/components/Nav.js
+++ /dev/null
@@ -1,152 +0,0 @@
-import Collapse from '@/components/Collapse'
-import LazyImage from '@/components/LazyImage'
-import { siteConfig } from '@/lib/config'
-import { useGlobal } from '@/lib/global'
-import Link from 'next/link'
-import { useEffect, useRef, useState } from 'react'
-import CONFIG from '../config'
-import { MenuItemCollapse } from './MenuItemCollapse'
-import { MenuItemDrop } from './MenuItemDrop'
-import RandomPostButton from './RandomPostButton'
-import SearchButton from './SearchButton'
-import { SvgIcon } from './SvgIcon'
-
-const Nav = props => {
- const { navBarTitle, fullWidth, siteInfo } = props
- const useSticky = !JSON.parse(siteConfig('GAME_AUTO_COLLAPSE_NAV_BAR', true))
- const navRef = useRef(null)
- const sentinalRef = useRef([])
- const handler = ([entry]) => {
- if (navRef && navRef.current && useSticky) {
- if (!entry.isIntersecting && entry !== undefined) {
- navRef.current?.classList.add('sticky-nav-full')
- } else {
- navRef.current?.classList.remove('sticky-nav-full')
- }
- } else {
- navRef.current?.classList.add('remove-sticky')
- }
- }
- useEffect(() => {
- const obvserver = new window.IntersectionObserver(handler)
- obvserver.observe(sentinalRef.current)
- return () => {
- if (sentinalRef.current) obvserver.unobserve(sentinalRef.current)
- }
- }, [sentinalRef])
- return (
- <>
-
-
-
-
-
- {/* */}
- {siteConfig('GAME_NAV_NOTION_ICON', null, CONFIG) ? (
-
- ) : (
-
- )}
-
-
- {navBarTitle ? (
-
{navBarTitle}
- ) : (
-
- {siteConfig('TITLE')}
- {/* ,{' '}{siteConfig('DESCRIPTION')} */}
-
- )}
-
-
-
- >
- )
-}
-
-const NavBar = props => {
- const { customMenu, customNav } = props
- const [isOpen, changeOpen] = useState(false)
- const toggleOpen = () => {
- changeOpen(!isOpen)
- }
- const collapseRef = useRef(null)
-
- const { locale } = useGlobal()
- let links = [
- {
- id: 2,
- name: locale.NAV.RSS,
- to: '/feed',
- show: siteConfig('ENABLE_RSS') && siteConfig('GAME_MENU_RSS', null, CONFIG),
- target: '_blank'
- },
- {
- icon: 'fas fa-search',
- name: locale.NAV.SEARCH,
- to: '/search',
- show: siteConfig('GAME_MENU_SEARCH', null, CONFIG)
- },
- {
- icon: 'fas fa-archive',
- name: locale.NAV.ARCHIVE,
- to: '/archive',
- show: siteConfig('GAME_MENU_ARCHIVE', null, CONFIG)
- },
- {
- icon: 'fas fa-folder',
- name: locale.COMMON.CATEGORY,
- to: '/category',
- show: siteConfig('GAME_MENU_CATEGORY', null, CONFIG)
- },
- { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag', show: siteConfig('GAME_MENU_TAG', null, CONFIG) }
- ]
- if (customNav) {
- links = links.concat(customNav)
- }
-
- // 如果 开启自定义菜单,则覆盖Page生成的菜单
- if (siteConfig('CUSTOM_MENU')) {
- links = customMenu
- }
-
- if (!links || links.length === 0) {
- return null
- }
-
- return (
-
-
- {links?.map((link, index) => (
-
- ))}
-
-
-
-
- {links?.map((link, index) => (
- collapseRef.current?.updateCollapseHeight(param)}
- />
- ))}
-
-
-
-
- {JSON.parse(siteConfig('GAME_MENU_RANDOM_POST', null, CONFIG)) &&
}
- {JSON.parse(siteConfig('GAME_MENU_SEARCH_BUTTON', null, CONFIG)) &&
}
-
-
- )
-}
-
-export default Nav
diff --git a/themes/game/components/NavBar.js b/themes/game/components/NavBar.js
deleted file mode 100644
index 0a146c40..00000000
--- a/themes/game/components/NavBar.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { MenuList } from './MenuList'
-
-export default function NavBar({ className }) {
- return (
-
- )
-}
diff --git a/themes/game/components/PostInfo.js b/themes/game/components/PostInfo.js
new file mode 100644
index 00000000..8b9b4983
--- /dev/null
+++ b/themes/game/components/PostInfo.js
@@ -0,0 +1,53 @@
+import NotionIcon from '@/components/NotionIcon'
+import Link from 'next/link'
+import TagItem from './TagItem'
+
+/**
+ * 文章详情页说明信息
+ */
+export default function PostInfo(props) {
+ const { post } = props
+
+ return (
+
+
+
+ {post?.type !== 'Page' && (
+ <>
+
+ {post?.category}
+
+ >
+ )}
+
+
+
+
+ {post?.title}
+
+
+ {post?.type !== 'Page' && (
+ <>
+
+ >
+ )}
+
+
+ )
+}
diff --git a/themes/game/components/SideBarContent.js b/themes/game/components/SideBarContent.js
index 1960b63f..e2efbeb3 100644
--- a/themes/game/components/SideBarContent.js
+++ b/themes/game/components/SideBarContent.js
@@ -1,5 +1,8 @@
+import { siteConfig } from '@/lib/config'
+import { deepClone } from '@/lib/utils'
import { useEffect, useRef } from 'react'
import { useGameGlobal } from '..'
+import CONFIG from '../config'
import { GameListNormal } from './GameListNormal'
import Logo from './Logo'
@@ -7,9 +10,9 @@ import Logo from './Logo'
* 侧拉抽屉的内容
*/
export default function SideBarContent() {
- const { allGames, sideBarVisible, setSideBarVisible, filterGames, setFilterGames } = useGameGlobal()
+ const { allNavPages, sideBarVisible, setSideBarVisible, filterGames, setFilterGames } = useGameGlobal()
const inputRef = useRef(null) // 创建对输入框的引用
-
+ const allGames = deepClone(allNavPages)
useEffect(() => {
if (sideBarVisible) {
setTimeout(() => {
@@ -21,7 +24,9 @@ export default function SideBarContent() {
const handleSearch = e => {
const search = e.target.value
if (!search || search === '') {
- setFilterGames(allGames?.filter(item => item.recommend))
+ setFilterGames(
+ allGames?.filter(item => item.tags?.some(t => t === siteConfig('GAME_RECOMMEND_TAG', 'Recommend', CONFIG)))
+ )
return
}
setFilterGames(
diff --git a/themes/game/components/TagItem.js b/themes/game/components/TagItem.js
index 0364e3fc..4f01fb72 100644
--- a/themes/game/components/TagItem.js
+++ b/themes/game/components/TagItem.js
@@ -1,11 +1,11 @@
import Link from 'next/link'
const TagItem = ({ tag }) => (
- (
-
+
+
{tag}
- )
+
)
export default TagItem
diff --git a/themes/game/components/TagItemMini.js b/themes/game/components/TagItemMini.js
new file mode 100644
index 00000000..3fe0c7bf
--- /dev/null
+++ b/themes/game/components/TagItemMini.js
@@ -0,0 +1,21 @@
+import Link from 'next/link'
+
+const TagItemMini = ({ tag, selected = false }) => {
+ return (
+
+ {/* # {tag.name} */}
+
+ # {tag.name}{' '}
+
+ {tag.count ? `${tag.count}` : ''}
+
+
+
+ )
+}
+
+export default TagItemMini
diff --git a/themes/game/index.js b/themes/game/index.js
index d7158faf..f65532ad 100644
--- a/themes/game/index.js
+++ b/themes/game/index.js
@@ -1,9 +1,11 @@
-import CusdisComponent from '@/components/CusdisComponent'
+import Comment from '@/components/Comment'
import { Draggable } from '@/components/Draggable'
import { AdSlot } from '@/components/GoogleAdsense'
import replaceSearchResult from '@/components/Mark'
+import NotionPage from '@/components/NotionPage'
+import ShareBar from '@/components/ShareBar'
import { siteConfig } from '@/lib/config'
-import { deepClone, isBrowser } from '@/lib/utils'
+import { deepClone, isBrowser, shuffleArray } from '@/lib/utils'
import Link from 'next/link'
import { createContext, useContext, useEffect, useRef, useState } from 'react'
import Announcement from './components/Announcement'
@@ -16,8 +18,11 @@ import FullScreen from './components/FullScreen'
import { GameListIndexCombine } from './components/GameListIndexCombine'
import { GameListRelate } from './components/GameListRealate'
import { GameListRecent } from './components/GameListRecent'
+import GroupCategory from './components/GroupCategory'
+import GroupTag from './components/GroupTag'
import Header from './components/Header'
-import NavBar from './components/NavBar'
+import { MenuList } from './components/MenuList'
+import PostInfo from './components/PostInfo'
import SearchNavBar from './components/SearchNavBar'
import SideBarContent from './components/SideBarContent'
import SideBarDrawer from './components/SideBarDrawer'
@@ -47,14 +52,22 @@ const LayoutBase = props => {
const [filterGames, setFilterGames] = useState(
deepClone(
- allNavPages?.filter(item => item.tags?.some(t => t === siteConfig('GAME_RECOMMEND_TAG', 'Recommend', CONFIG)))
+ allNavPages?.filter(item =>
+ item.tags?.some(
+ t => t === siteConfig('GAME_RECOMMEND_TAG', 'Recommend', CONFIG)
+ )
+ )
)
)
const [recentGames, setRecentGames] = useState([])
const [sideBarVisible, setSideBarVisible] = useState(false)
useEffect(() => {
- setRecentGames(localStorage.getItem('recent_games') ? JSON.parse(localStorage.getItem('recent_games')) : [])
+ setRecentGames(
+ localStorage.getItem('recent_games')
+ ? JSON.parse(localStorage.getItem('recent_games'))
+ : []
+ )
}, [])
return (
@@ -74,37 +87,34 @@ const LayoutBase = props => {
id='theme-game'
className={`${siteConfig('FONT_STYLE')} w-full h-full min-h-screen justify-center bg-[#83FFE7] dark:bg-black dark:text-gray-300 scroll-smooth`}>
+
{/* 左右布局 */}
-
- {/* 左侧 */}
+
+ {/* PC端左侧 */}
- {/* 顶部 */}
-
-
+
-
+
+ {/* 左侧广告栏目 */}
-
-
-
{/* 右侧 */}
-
- {children}
+
+ {children}
-
+
@@ -127,11 +137,38 @@ const LayoutBase = props => {
* @returns
*/
const LayoutIndex = props => {
+ const { tagOptions, currentTag, categoryOptions, currentCategory } = props
return (
<>
+ {/* 首页移动端顶部导航 */}
+
+
+
+ {/* 最近游戏 */}
+ {/* 游戏列表 */}
-
+
+ {/* 主区域下方 */}
+
+ {/* 标签汇总 */}
+
+
+
+
+
+ {/* 广告 */}
+
+
+ {/* 站点公告信息 */}
+
>
)
}
@@ -159,9 +196,9 @@ const LayoutPostList = props => {
<>
{tag &&
}
{siteConfig('POST_LIST_STYLE') === 'page' ? (
-
+
) : (
-
+
)}
>
)
@@ -224,7 +261,11 @@ const LayoutArchive = props => {
<>
{Object.keys(archivePosts).map(archiveTitle => (
-
+
))}
>
@@ -237,23 +278,19 @@ const LayoutArchive = props => {
* @returns
*/
const LayoutSlug = props => {
- const { post, allNavPages, lock, validPassword } = props
- const game = post
+ const { post, allNavPages, recommendPosts, lock, validPassword } = props
+ const game = deepClone(post)
const [loading, setLoading] = useState(false)
// const [url, setUrl] = useState(game?.ext?.href)
- // 替换成随机推荐和相关游戏
- const relateGames = allNavPages
- const randomGames = allNavPages
+ const relateGames = recommendPosts
+ const randomGames = shuffleArray(deepClone(allNavPages))
// 将当前游戏加入到最近游玩
useEffect(() => {
- // if (!url || url !== game?.ext?.href) {
- // // 游戏路径
- // setUrl(game?.ext?.href)
- // }
-
// 更新最新游戏
- const recentGames = localStorage.getItem('recent_games') ? JSON.parse(localStorage.getItem('recent_games')) : []
+ const recentGames = localStorage.getItem('recent_games')
+ ? JSON.parse(localStorage.getItem('recent_games'))
+ : []
const existedIndex = recentGames.findIndex(item => item?.id === game?.id)
if (existedIndex === -1) {
@@ -275,15 +312,21 @@ const LayoutSlug = props => {
}
// 绑定加载事件
- if (iframe.attachEvent) {
- iframe.attachEvent('onload', iframeLoaded)
+ if (iframe?.attachEvent) {
+ iframe?.attachEvent('onload', iframeLoaded)
} else {
- iframe.onload = iframeLoaded
+ if (iframe) iframe.onload = iframeLoaded
}
// 更改iFrame的title
- if (document?.getElementById('game-wrapper')?.contentDocument.querySelector('title')?.textContent) {
- document.getElementById('game-wrapper').contentDocument.querySelector('title').textContent = `${
+ if (
+ document
+ ?.getElementById('game-wrapper')
+ ?.contentDocument.querySelector('title')?.textContent
+ ) {
+ document
+ .getElementById('game-wrapper')
+ .contentDocument.querySelector('title').textContent = `${
game?.title || ''
} - Play ${game?.title || ''} on ${siteConfig('TITLE')}`
}
@@ -294,103 +337,101 @@ const LayoutSlug = props => {
{lock &&
}
{!lock && (
-
- <>
- {/*
-
-
-
-
*/}
- {/* 游戏区域 */}
-
- {/* 移动端返回主页按钮 */}
-
-
-
-
- {' '}
- {
- document.querySelector('.game-info').scrollIntoView({
- behavior: 'smooth',
- block: 'end',
- inline: 'nearest'
- })
- }}>
- G
-
-
-
+
+ {/* 游戏区域 */}
+
+ {/* 移动端返回主页按钮 */}
+
+
+
+
+ {' '}
+ {
+ document.querySelector('.game-info').scrollIntoView({
+ behavior: 'smooth',
+ block: 'end',
+ inline: 'nearest'
+ })
+ }}>
+ G
+
+
+
-
-
- {/* Loading遮罩 */}
- {loading && (
-
-
-
-
- {siteConfig('TITLE')}
-
- {siteConfig('DESCRIPTION')}
-
-
- {/* 游戏封面图 */}
- {/* eslint-disable-next-line @next/next/no-img-element */}
- {game?.img &&

}
+
+ {/* 游戏区 */}
+
+ {/* Loading遮罩 */}
+ {loading && (
+
+
+
+
+ {siteConfig('TITLE')}
+
+
+ {siteConfig('DESCRIPTION')}
+
- )}
-
-
- {/* 游戏窗口装饰器 */}
- {game && !loading && (
-
- {/* 加入全屏按钮 */}
-
-
- )}
-
-
- {/* 游戏资讯 */}
-
-
-
+ {/* 游戏封面图 */}
+ {/* eslint-disable-next-line @next/next/no-img-element */}
+ {game?.img && (
+

+ )}
-
{game?.title}
-
- Play {game?.title || ''} on {siteConfig('TITLE', '')}
-
-
{siteConfig('DESCRIPTION')}
-
+ )}
- {game && (
-
- )}
+
+
+ {/* 游戏窗口装饰器 */}
+ {game && !loading && (
+
+ {/* 加入全屏按钮 */}
+
+
+ )}
+
+
+ {/* 游戏资讯 */}
+
+ {/* 关联游戏 */}
+
+
+
+ {game && (
+
+
+
+ {/* 广告嵌入 */}
+
+
+
+
+ )}
+
-
-
-
- {/* 其它游戏列表 */}
-
-
-
- >
+ {/* 其它游戏列表 */}
+
)}
>
@@ -416,15 +457,21 @@ const LayoutCategoryIndex = props => {
return (
<>
-
+
{categoryOptions?.map(category => {
return (
-
+
-
+ {/* */}
{category.name}({category.count})
@@ -445,20 +492,17 @@ const LayoutTagIndex = props => {
return (
<>