+
{post.title}
-
-
+
+
diff --git a/themes/movie/components/Header.js b/themes/movie/components/Header.js
index ae5e3a2a..223df3e5 100644
--- a/themes/movie/components/Header.js
+++ b/themes/movie/components/Header.js
@@ -1,26 +1,163 @@
import Link from 'next/link'
import { siteConfig } from '@/lib/config'
-import { MenuListTop } from './MenuListTop'
+import { useMovieGlobal } from '..'
+import Collapse from '@/components/Collapse'
+import { MenuItemCollapse } from './MenuItemCollapse'
+import { useGlobal } from '@/lib/global'
+import CONFIG from '../config'
+import { MenuItemDrop } from './MenuItemDrop'
+import { useEffect, useState } from 'react'
+import { useRouter } from 'next/router'
/**
* 网站顶部
* @returns
*/
export const Header = props => {
+ const { collapseRef, searchModal } = useMovieGlobal()
+ const router = useRouter()
+ const { customNav, customMenu } = props
+ const { locale } = useGlobal()
+ const [isOpen, setIsOpen] = useState(false)
+ const [showSearch, setShowSearch] = useState(false)
+ const toggleMenuOpen = () => {
+ setIsOpen(!isOpen)
+ }
+ let links = [
+ {
+ id: 1,
+ icon: 'fa-solid fa-house',
+ name: locale.NAV.INDEX,
+ to: '/',
+ show: siteConfig('MOVIE_MENU_INDEX', null, CONFIG)
+ },
+ {
+ id: 2,
+ icon: 'fas fa-search',
+ name: locale.NAV.SEARCH,
+ to: '/search',
+ show: siteConfig('MOVIE_MENU_SEARCH', null, CONFIG)
+ },
+ {
+ id: 3,
+ icon: 'fas fa-archive',
+ name: locale.NAV.ARCHIVE,
+ to: '/archive',
+ show: siteConfig('MOVIE_MENU_ARCHIVE', null, CONFIG)
+ }
+ // { icon: 'fas fa-folder', name: locale.COMMON.CATEGORY, to: '/category', show: siteConfig('MENU_CATEGORY', null, CONFIG) },
+ // { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag', show: siteConfig('MENU_TAG', null, CONFIG) }
+ ]
+
+ if (customNav) {
+ links = links.concat(customNav)
+ }
+
+ for (let i = 0; i < links.length; i++) {
+ if (links[i].id !== i) {
+ links[i].id = i
+ }
+ }
+
+ // 如果 开启自定义菜单,则覆盖Page生成的菜单
+ if (siteConfig('CUSTOM_MENU')) {
+ links = customMenu
+ }
+
+ // 展示搜索框
+ const toggleShowSearchInput = () => {
+ if (siteConfig('ALGOLIA_APP_ID')) {
+ searchModal.current.openSearch()
+ } else {
+ setShowSearch(!showSearch)
+ }
+ }
+
+ useEffect(() => {
+ if (showSearch) {
+ setTimeout(() => {
+ document.getElementById('search').focus()
+ }, 100);
+ }
+ }, [showSearch])
+
+ const onKeyUp = e => {
+ if (e.keyCode === 13) {
+ const search = document.getElementById('search').value
+ if (search) {
+ router.push({ pathname: '/search/' + search })
+ }
+ }
+ }
+
+ const handleSearch = () => {
+ const search = document.getElementById('search').value
+ if (search) {
+ router.push({ pathname: '/search/' + search })
+ }
+ }
+
return (
-
-
+ <>
+
+ href='/'
+ className='whitespace-nowrap py-6 text-2xl md:text-3xl font-bold text-gray-dark no-underline flex items-center'>
{siteConfig('TITLE')}
-
+
+
{/* 右侧菜单 */}
-
+ <>
+
+
+
+
+
+
+
+
+
+
+ {/* 移动端按钮 */}
+
+
+ {isOpen ? : }
+
+
+ >
-
-
+
+
+
+ {/* 移动端菜单 */}
+
+
+ >
)
}
diff --git a/themes/movie/components/MenuItemCollapse.js b/themes/movie/components/MenuItemCollapse.js
new file mode 100644
index 00000000..0f91f1d4
--- /dev/null
+++ b/themes/movie/components/MenuItemCollapse.js
@@ -0,0 +1,77 @@
+import Collapse from '@/components/Collapse'
+import Link from 'next/link'
+import { useState } from 'react'
+
+/**
+ * 折叠菜单
+ * @param {*} param0
+ * @returns
+ */
+export const MenuItemCollapse = props => {
+ const { link } = props
+ const [show, changeShow] = useState(false)
+ const hasSubMenu = link?.subMenus?.length > 0
+
+ const [isOpen, changeIsOpen] = useState(false)
+
+ const toggleShow = () => {
+ changeShow(!show)
+ }
+
+ const toggleOpenSubMenu = () => {
+ changeIsOpen(!isOpen)
+ }
+
+ if (!link || !link.show) {
+ return null
+ }
+
+ return (
+ <>
+
+ {!hasSubMenu && (
+
+
+ {link?.icon && }
+ {link?.name}
+
+
+ )}
+ {hasSubMenu && (
+
+
+ {link?.icon && }
+ {link?.name}
+
+
+
+ )}
+
+
+ {/* 折叠子菜单 */}
+ {hasSubMenu && (
+
+ {link.subMenus.map((sLink, index) => {
+ return (
+
+
+
+ {link?.icon && } {sLink.title}
+
+
+
+ )
+ })}
+
+ )}
+ >
+ )
+}
diff --git a/themes/movie/components/MenuItemDrop.js b/themes/movie/components/MenuItemDrop.js
index 501140a4..5d2f8a8d 100644
--- a/themes/movie/components/MenuItemDrop.js
+++ b/themes/movie/components/MenuItemDrop.js
@@ -18,7 +18,7 @@ export const MenuItemDrop = ({ link }) => {
{link?.icon && } {link?.name}
{hasSubMenu && }
diff --git a/themes/movie/components/MenuListTop.js b/themes/movie/components/MenuListTop.js
deleted file mode 100644
index d79b2ab5..00000000
--- a/themes/movie/components/MenuListTop.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useGlobal } from '@/lib/global'
-import CONFIG from '../config'
-import { siteConfig } from '@/lib/config'
-import { MenuItemDrop } from './MenuItemDrop'
-
-export const MenuListTop = props => {
- const { customNav, customMenu } = props
- const { locale } = useGlobal()
-
- let links = [
- {
- id: 1,
- icon: 'fa-solid fa-house',
- name: locale.NAV.INDEX,
- to: '/',
- show: siteConfig('HEXO_MENU_INDEX', null, CONFIG)
- },
- {
- id: 2,
- icon: 'fas fa-search',
- name: locale.NAV.SEARCH,
- to: '/search',
- show: siteConfig('HEXO_MENU_SEARCH', null, CONFIG)
- },
- {
- id: 3,
- icon: 'fas fa-archive',
- name: locale.NAV.ARCHIVE,
- to: '/archive',
- show: siteConfig('HEXO_MENU_ARCHIVE', null, CONFIG)
- }
- // { icon: 'fas fa-folder', name: locale.COMMON.CATEGORY, to: '/category', show: siteConfig('MENU_CATEGORY', null, CONFIG) },
- // { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag', show: siteConfig('MENU_TAG', null, CONFIG) }
- ]
-
- if (customNav) {
- links = links.concat(customNav)
- }
-
- for (let i = 0; i < links.length; i++) {
- if (links[i].id !== i) {
- links[i].id = i
- }
- }
-
- // 如果 开启自定义菜单,则覆盖Page生成的菜单
- if (siteConfig('CUSTOM_MENU')) {
- links = customMenu
- }
-
- if (!links || links.length === 0) {
- return null
- }
-
- return (
- <>
-
- >
- )
-}
diff --git a/themes/movie/components/Nav.js b/themes/movie/components/Nav.js
deleted file mode 100644
index 08f5ca56..00000000
--- a/themes/movie/components/Nav.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import { siteConfig } from '@/lib/config'
-import { useGlobal } from '@/lib/global'
-import CONFIG from '../config'
-import { MenuItemDrop } from './MenuItemDrop'
-
-/**
- * 菜单导航
- * @param {*} props
- * @returns
- */
-export const Nav = props => {
- const { customNav, customMenu } = props
- const { locale } = useGlobal()
-
- let links = [
- {
- id: 1,
- icon: 'fas fa-search',
- name: locale.NAV.SEARCH,
- to: '/search',
- show: siteConfig('EXAMPLE_MENU_SEARCH', null, CONFIG)
- },
- {
- id: 2,
- icon: 'fas fa-archive',
- name: locale.NAV.ARCHIVE,
- to: '/archive',
- show: siteConfig('EXAMPLE_MENU_ARCHIVE', null, CONFIG)
- },
- {
- id: 3,
- icon: 'fas fa-folder',
- name: locale.COMMON.CATEGORY,
- to: '/category',
- show: siteConfig('EXAMPLE_MENU_CATEGORY', null, CONFIG)
- },
- {
- id: 4,
- icon: 'fas fa-tag',
- name: locale.COMMON.TAGS,
- to: '/tag',
- show: siteConfig('EXAMPLE_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 (
-
- )
-}
diff --git a/themes/movie/config.js b/themes/movie/config.js
index 181d3a93..48403075 100644
--- a/themes/movie/config.js
+++ b/themes/movie/config.js
@@ -3,12 +3,12 @@
*/
const CONFIG = {
// 菜单配置
- EXAMPLE_MENU_CATEGORY: true, // 显示分类
- EXAMPLE_MENU_TAG: true, // 显示标签
- EXAMPLE_MENU_ARCHIVE: true, // 显示归档
- EXAMPLE_MENU_SEARCH: true, // 显示搜索
+ MOVIE_MENU_CATEGORY: true, // 显示分类
+ MOVIE_MENU_TAG: true, // 显示标签
+ MOVIE_MENU_ARCHIVE: true, // 显示归档
+ MOVIE_MENU_SEARCH: true, // 显示搜索
- EXAMPLE_POST_LIST_COVER: true // 列表显示文章封面
+ MOVIE_POST_LIST_COVER: true // 列表显示文章封面
}
export default CONFIG
diff --git a/themes/movie/index.js b/themes/movie/index.js
index 2aaa95da..e34f0e83 100644
--- a/themes/movie/index.js
+++ b/themes/movie/index.js
@@ -1,37 +1,32 @@
'use client'
-import CONFIG from './config'
-import { createContext, useContext, useEffect, useRef } from 'react'
-import { Header } from './components/Header'
-import { Nav } from './components/Nav'
-import { Footer } from './components/Footer'
-import { Title } from './components/Title'
-import { SideBar } from './components/SideBar'
+import AlgoliaSearchModal from '@/components/AlgoliaSearchModal'
+import Comment from '@/components/Comment'
+import replaceSearchResult from '@/components/Mark'
+import NotionPage from '@/components/NotionPage'
+import ShareBar from '@/components/ShareBar'
+import { siteConfig } from '@/lib/config'
+import { useGlobal } from '@/lib/global'
+import { isBrowser } from '@/lib/utils'
+import { Transition } from '@headlessui/react'
+import { useRouter } from 'next/router'
+import { createContext, useContext, useEffect, useRef, useState } from 'react'
+import ArchiveDateList from './components/ArchiveDateList'
+import { ArticleInfo } from './components/ArticleInfo'
+import { ArticleLock } from './components/ArticleLock'
+import BlogListGroupByDate from './components/BlogListGroupByDate'
import { BlogListPage } from './components/BlogListPage'
import { BlogListScroll } from './components/BlogListScroll'
-import { useGlobal } from '@/lib/global'
-import { ArticleLock } from './components/ArticleLock'
-import { ArticleInfo } from './components/ArticleInfo'
-import JumpToTopButton from './components/JumpToTopButton'
-import NotionPage from '@/components/NotionPage'
-import Comment from '@/components/Comment'
-import ShareBar from '@/components/ShareBar'
-import SearchInput from './components/SearchInput'
-import replaceSearchResult from '@/components/Mark'
-import { isBrowser } from '@/lib/utils'
-import BlogListGroupByDate from './components/BlogListGroupByDate'
-import CategoryItem from './components/CategoryItem'
-import TagItem from './components/TagItem'
-import { useRouter } from 'next/router'
-import { Transition } from '@headlessui/react'
-import { Style } from './style'
-import { siteConfig } from '@/lib/config'
-import AlgoliaSearchModal from '@/components/AlgoliaSearchModal'
-import LatestPostsGroup from './components/LatestPostsGroup'
import CategoryGroup from './components/CategoryGroup'
-import { formatDateFmt } from '@/lib/utils/formatDate'
-import ArchiveDateList from './components/ArchiveDateList'
+import CategoryItem from './components/CategoryItem'
+import { Footer } from './components/Footer'
+import { Header } from './components/Header'
+import JumpToTopButton from './components/JumpToTopButton'
+import LatestPostsGroup from './components/LatestPostsGroup'
import TagGroups from './components/TagGroups'
+import TagItem from './components/TagItem'
+import CONFIG from './config'
+import { Style } from './style'
// 主题全局状态
const ThemeGlobalMovie = createContext()
@@ -47,56 +42,44 @@ export const useMovieGlobal = () => useContext(ThemeGlobalMovie)
const LayoutBase = props => {
const { children, slotTop } = props
const { onLoading, fullWidth } = useGlobal()
- const router = useRouter()
- const { category, tag } = props
- const searchModal = useRef(null)
+ const collapseRef = useRef(null)
- // 增加一个状态以触发 Transition 组件的动画
- // const [showTransition, setShowTransition] = useState(true)
- // useEffect(() => {
- // // 当 location 或 children 发生变化时,触发动画
- // setShowTransition(false)
- // setTimeout(() => setShowTransition(true), 5)
- // }, [onLoading])
+ const searchModal = useRef(null)
+ const [expandMenu, updateExpandMenu] = useState(false)
return (
-
+
+ id='theme-movie'
+ className={`${siteConfig('FONT_STYLE')} dark:text-gray-300 duration-300 transition-all bg-white dark:bg-[#2A2A2A] scroll-smooth min-h-screen flex flex-col justify-between`}>
{/* 页头 */}
{/* 主体 */}
-
+
{/* 标题栏 */}
{/* {fullWidth ? null : } */}
+ }>
{/* 内容 */}
+ enter='transition ease-in-out duration-700 transform order-first'
+ enterFrom='opacity-0 translate-y-16'
+ enterTo='opacity-100'
+ leave='transition ease-in-out duration-300 transform'
+ leaveFrom='opacity-100 translate-y-0'
+ leaveTo='opacity-0 -translate-y-16'
+ unmount={false}>
{/* 嵌入模块 */}
{slotTop}
{children}
@@ -112,7 +95,7 @@ const LayoutBase = props => {
{/* 回顶按钮 */}
-
+
@@ -135,15 +118,7 @@ const LayoutIndex = props => {
* @returns
*/
const LayoutPostList = props => {
- return (
- <>
- {siteConfig('POST_LIST_STYLE') === 'page' ? (
-
- ) : (
-
- )}
- >
- )
+ return <>{siteConfig('POST_LIST_STYLE') === 'page' ? : }>
}
/**
@@ -174,16 +149,18 @@ const LayoutSlug = props => {
}, [post])
return (
<>
- {lock ? (
-
- ) : (
-
+ {!lock
+ ? (
+
- )}
+ )
+ : (
+
+ )}
>
)
}
@@ -215,27 +192,27 @@ const Layout404 = props => {
return (
<>
-
- {locale.COMMON.NO_RESULTS_FOUND}
-
-
+
+ {locale.COMMON.NO_RESULTS_FOUND}
+
+
-
+
{/* 底部导航 */}
-
+
@@ -282,13 +259,9 @@ const LayoutArchive = props => {
const { archivePosts } = props
return (
<>
-
+
{Object.keys(archivePosts).map(archiveTitle => (
-
+
))}
>
@@ -304,7 +277,7 @@ const LayoutCategoryIndex = props => {
const { categoryOptions } = props
return (
<>
-
+
{categoryOptions?.map(category => (
))}
@@ -322,7 +295,7 @@ const LayoutTagIndex = props => {
const { tagOptions } = props
return (
<>
-
{locale.COMMON.NO_RESULTS_FOUND}
--
{locale.COMMON.NO_RESULTS_FOUND}
++