mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 15:09:13 +00:00
Merge branch 'main' into feat/post/extract-page-content
This commit is contained in:
@@ -3,7 +3,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import algoliasearch from 'algoliasearch'
|
||||
import throttle from 'lodash/throttle'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import {
|
||||
Fragment,
|
||||
@@ -356,7 +356,7 @@ function TagGroups() {
|
||||
<div id='tags-group' className='dark:border-gray-700 space-y-2'>
|
||||
{firstTenTags?.map((tag, index) => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
key={index}
|
||||
href={`/tag/${encodeURIComponent(tag.name)}`}
|
||||
@@ -372,7 +372,7 @@ function TagGroups() {
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import useWindowSize from '@/hooks/useWindowSize'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { THEMES, saveDarkModeToLocalStorage } from '@/themes/theme'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
|
||||
@@ -198,23 +198,23 @@ export default function CustomContextMenu(props) {
|
||||
)}
|
||||
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY && (
|
||||
<Link
|
||||
<SmartLink
|
||||
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'>
|
||||
<i className='fa-solid fa-square-minus mr-2' />
|
||||
<div className='whitespace-nowrap'>{locale.MENU.CATEGORY}</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG && (
|
||||
<Link
|
||||
<SmartLink
|
||||
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'>
|
||||
<i className='fa-solid fa-tag mr-2' />
|
||||
<div className='whitespace-nowrap'>{locale.MENU.TAGS}</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ const Player = () => {
|
||||
<link
|
||||
rel='stylesheet'
|
||||
type='text/css'
|
||||
href='https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css'
|
||||
href='https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.css'
|
||||
/>
|
||||
{meting ? (
|
||||
<meting-js
|
||||
|
||||
52
components/SmartLink.js
Normal file
52
components/SmartLink.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import Link from 'next/link'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
// 过滤 <a> 标签不能识别的 props
|
||||
const filterDOMProps = props => {
|
||||
const { passHref, legacyBehavior, ...rest } = props
|
||||
return rest
|
||||
}
|
||||
|
||||
const SmartLink = ({ href, children, ...rest }) => {
|
||||
const LINK = siteConfig('LINK')
|
||||
|
||||
// 获取 URL 字符串用于判断是否是外链
|
||||
let urlString = ''
|
||||
|
||||
if (typeof href === 'string') {
|
||||
urlString = href
|
||||
} else if (
|
||||
typeof href === 'object' &&
|
||||
href !== null &&
|
||||
typeof href.pathname === 'string'
|
||||
) {
|
||||
urlString = href.pathname
|
||||
}
|
||||
|
||||
const isExternal = urlString.startsWith('http') && !urlString.startsWith(LINK)
|
||||
|
||||
if (isExternal) {
|
||||
// 对于外部链接,必须是 string 类型
|
||||
const externalUrl =
|
||||
typeof href === 'string' ? href : new URL(href.pathname, LINK).toString()
|
||||
|
||||
return (
|
||||
<a
|
||||
href={externalUrl}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
{...filterDOMProps(rest)}>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
// 内部链接(可为对象形式)
|
||||
return (
|
||||
<Link href={href} {...rest}>
|
||||
{children}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
export default SmartLink
|
||||
@@ -1,5 +1,5 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
/**
|
||||
* 跳转仪表盘的按钮
|
||||
@@ -24,7 +24,7 @@ export default function DashboardButton({ className }) {
|
||||
<button
|
||||
type='button'
|
||||
className={`${className || ''} text-white bg-gray-800 hover:bg-gray-900 hover:ring-4 hover:ring-gray-300 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-5 py-2 me-2 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700`}>
|
||||
<Link href='/dashboard'>仪表盘</Link>
|
||||
<SmartLink href='/dashboard'>仪表盘</SmartLink>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import formatDate from '@/lib/utils/formatDate'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import DashboardSignOutButton from './DashboardSignOutButton'
|
||||
|
||||
/**
|
||||
@@ -25,11 +25,11 @@ export default function DashboardHeader() {
|
||||
<div class='font-medium dark:text-white'>
|
||||
<div className='flex items-center gap-x-2'>
|
||||
<span>{user?.fullName}</span>
|
||||
<Link href='/dashboard/membership'>
|
||||
<SmartLink href='/dashboard/membership'>
|
||||
<span class='bg-gray-100 text-gray-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-gray-300'>
|
||||
普通用户
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
<div className='text-sm text-gray-500 gap-x-2 flex dark:text-gray-400'>
|
||||
<span>{user?.username}</span>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 联盟行销
|
||||
@@ -140,11 +140,11 @@ export default function DashboardItemAffliate() {
|
||||
for='remember'
|
||||
className='ms-2 text-sm font-medium text-gray-900 dark:text-gray-300'>
|
||||
我以阅读并同意{' '}
|
||||
<Link
|
||||
<SmartLink
|
||||
href='/terms-of-use'
|
||||
className='text-blue-600 hover:underline dark:text-blue-500'>
|
||||
服务协议
|
||||
</Link>
|
||||
</SmartLink>
|
||||
.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 仪表盘菜单
|
||||
@@ -43,12 +43,12 @@ export default function DashboardMenuList() {
|
||||
className={`rounded-lg cursor-pointer block ${
|
||||
isActive ? 'bg-blue-100 text-blue-600' : 'hover:bg-gray-100'
|
||||
}`}>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={item.href}
|
||||
className='block py-2 px-4 w-full items-center justify-center'>
|
||||
<i className={`${item.icon} w-6 mr-2`}></i>
|
||||
<span className='whitespace-nowrap'>{item.title}</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -32,7 +32,7 @@ module.exports = {
|
||||
MUSIC_PLAYER_LRC_TYPE: process.env.NEXT_PUBLIC_MUSIC_PLAYER_LRC_TYPE || '0', // 歌词显示类型,可选值: 3 | 1 | 0(0:禁用 lrc 歌词,1:lrc 格式的字符串,3:lrc 文件 url)(前提是有配置歌词路径,对 meting 无效)
|
||||
MUSIC_PLAYER_CDN_URL:
|
||||
process.env.NEXT_PUBLIC_MUSIC_PLAYER_CDN_URL ||
|
||||
'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js',
|
||||
'https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.js',
|
||||
MUSIC_PLAYER_ORDER: process.env.NEXT_PUBLIC_MUSIC_PLAYER_ORDER || 'list', // 默认播放方式,顺序 list,随机 random
|
||||
MUSIC_PLAYER_AUDIO_LIST: [
|
||||
// 示例音乐列表。除了以下配置外,还可配置歌词,具体配置项看此文档 https://aplayer.js.org/#/zh-Hans/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from './global'
|
||||
import { deepClone, isUrl } from './utils'
|
||||
import { deepClone, isUrlLikePath } from './utils'
|
||||
|
||||
/**
|
||||
* 读取配置顺序
|
||||
@@ -146,7 +146,7 @@ export const convertVal = val => {
|
||||
}
|
||||
|
||||
// 检测是否为 URL
|
||||
if (isUrl(val)) {
|
||||
if (isUrlLikePath(val)) {
|
||||
return val
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ export function GlobalContextProvider(props) {
|
||||
) // 默认语言
|
||||
const [theme, setTheme] = useState(NOTION_CONFIG?.THEME || THEME) // 默认博客主题
|
||||
const [THEME_CONFIG, SET_THEME_CONFIG] = useState(null) // 主题配置
|
||||
const [isLiteMode,setLiteMode] = useState(false)
|
||||
|
||||
const defaultDarkMode = NOTION_CONFIG?.APPEARANCE || APPEARANCE
|
||||
const [isDarkMode, updateDarkMode] = useState(defaultDarkMode === 'dark') // 默认深色模式
|
||||
@@ -85,10 +86,17 @@ export function GlobalContextProvider(props) {
|
||||
// 添加路由变化时的语言处理
|
||||
useEffect(() => {
|
||||
initLocale(router.locale, changeLang, updateLocale)
|
||||
}, [router])
|
||||
// 处理极简模式
|
||||
if (router.query.lite && router.query.lite==='true') {
|
||||
setLiteMode(true)
|
||||
}
|
||||
}, [router])
|
||||
|
||||
|
||||
// 首次加载成功
|
||||
useEffect(() => {
|
||||
initDarkMode(updateDarkMode, defaultDarkMode)
|
||||
// 处理多语言自动重定向
|
||||
if (
|
||||
NOTION_CONFIG?.REDIRECT_LANG &&
|
||||
JSON.parse(NOTION_CONFIG?.REDIRECT_LANG)
|
||||
@@ -107,6 +115,7 @@ export function GlobalContextProvider(props) {
|
||||
const newUrl = `${url}${url.includes('?') ? '&' : '?'}theme=${themeStr}`
|
||||
router.push(newUrl)
|
||||
}
|
||||
|
||||
if (!onLoading) {
|
||||
setOnLoading(true)
|
||||
}
|
||||
@@ -134,6 +143,7 @@ export function GlobalContextProvider(props) {
|
||||
return (
|
||||
<GlobalContext.Provider
|
||||
value={{
|
||||
isLiteMode,
|
||||
isLoaded,
|
||||
isSignedIn,
|
||||
user,
|
||||
|
||||
@@ -4,11 +4,7 @@ import formatDate from '../utils/formatDate'
|
||||
// import { createHash } from 'crypto'
|
||||
import md5 from 'js-md5'
|
||||
import { siteConfig } from '../config'
|
||||
import {
|
||||
checkStartWithHttp,
|
||||
convertUrlStartWithOneSlash,
|
||||
getLastSegmentFromUrl
|
||||
} from '../utils'
|
||||
import { convertUrlStartWithOneSlash, getLastSegmentFromUrl, isHttpLink, isMailOrTelLink } from '../utils'
|
||||
import { extractLangPrefix } from '../utils/pageId'
|
||||
import { mapImgUrl } from './mapImage'
|
||||
import notionAPI from '@/lib/notion/getNotionAPI'
|
||||
@@ -85,8 +81,9 @@ export default async function getPageProperties(
|
||||
const fieldNames = BLOG.NOTION_PROPERTY_NAME
|
||||
if (fieldNames) {
|
||||
Object.keys(fieldNames).forEach(key => {
|
||||
if (fieldNames[key] && properties[fieldNames[key]])
|
||||
if (fieldNames[key] && properties[fieldNames[key]]) {
|
||||
properties[key] = properties[fieldNames[key]]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -190,9 +187,12 @@ export function adjustPageProperties(properties, NOTION_CONFIG) {
|
||||
}
|
||||
|
||||
// http or https 开头的视为外链
|
||||
if (checkStartWithHttp(properties?.href)) {
|
||||
if (isHttpLink(properties?.href)) {
|
||||
properties.href = properties?.slug
|
||||
properties.target = '_blank'
|
||||
} else if (isMailOrTelLink(properties?.href)) {
|
||||
properties.href = properties?.slug
|
||||
properties.target = '_self'
|
||||
} else {
|
||||
properties.target = '_self'
|
||||
// 伪静态路径右侧拼接.html
|
||||
@@ -238,7 +238,7 @@ export function adjustPageProperties(properties, NOTION_CONFIG) {
|
||||
*/
|
||||
function generateCustomizeSlug(postProperties, NOTION_CONFIG) {
|
||||
// 外链不处理
|
||||
if (checkStartWithHttp(postProperties.slug)) {
|
||||
if (isHttpLink(postProperties.slug)) {
|
||||
return postProperties.slug
|
||||
}
|
||||
let fullPrefix = ''
|
||||
|
||||
@@ -119,10 +119,19 @@ const compressImage = (image, width, quality = 50, fmt = 'webp') => {
|
||||
width = siteConfig('IMAGE_COMPRESS_WIDTH')
|
||||
}
|
||||
|
||||
// 将URL解析为一个对象
|
||||
const urlObj = new URL(image)
|
||||
// 获取URL参数
|
||||
const params = new URLSearchParams(urlObj.search)
|
||||
|
||||
let urlObj
|
||||
let params
|
||||
try {
|
||||
// 将URL解析为一个对象
|
||||
urlObj = new URL(image)
|
||||
// 获取URL参数
|
||||
params = new URLSearchParams(urlObj.search)
|
||||
} catch (err) {
|
||||
// 捕获异常并打印错误的url
|
||||
console.error('compressImage: Invalid URL:', image, err)
|
||||
return image
|
||||
}
|
||||
|
||||
// Notion图床
|
||||
if (
|
||||
|
||||
@@ -2,6 +2,31 @@ import BLOG from '@/blog.config'
|
||||
import algoliasearch from 'algoliasearch'
|
||||
import { getPageContentText } from '@/lib/notion/getPageContentText'
|
||||
|
||||
// 全局初始化 Algolia 客户端和索引
|
||||
let algoliaClient
|
||||
let algoliaIndex
|
||||
|
||||
const initAlgolia = () => {
|
||||
if (!algoliaClient) {
|
||||
if (
|
||||
!BLOG.ALGOLIA_APP_ID ||
|
||||
!BLOG.ALGOLIA_ADMIN_APP_KEY ||
|
||||
!BLOG.ALGOLIA_INDEX
|
||||
) {
|
||||
console.error('Algolia configuration is missing')
|
||||
}
|
||||
algoliaClient = algoliasearch(
|
||||
BLOG.ALGOLIA_APP_ID,
|
||||
BLOG.ALGOLIA_ADMIN_APP_KEY
|
||||
)
|
||||
algoliaIndex = algoliaClient.initIndex(BLOG.ALGOLIA_INDEX)
|
||||
}
|
||||
return { client: algoliaClient, index: algoliaIndex }
|
||||
}
|
||||
|
||||
// 初始化全局实例
|
||||
initAlgolia()
|
||||
|
||||
/**
|
||||
* 生成全文索引
|
||||
* @param {*} allPages
|
||||
@@ -15,17 +40,57 @@ const generateAlgoliaSearch = ({ allPages, force = false }) => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查数据是否需要从algolia删除
|
||||
* @param {*} props
|
||||
*/
|
||||
export const checkDataFromAlgolia = async props => {
|
||||
const { allPages } = props
|
||||
const deletions = (allPages || [])
|
||||
.map(p => {
|
||||
if (p && (p.password || p.status === 'Draft')) {
|
||||
return deletePostDataFromAlgolia(p)
|
||||
}
|
||||
})
|
||||
.filter(Boolean) // 去除 undefined
|
||||
await Promise.all(deletions)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
* @param post
|
||||
*/
|
||||
const deletePostDataFromAlgolia = async post => {
|
||||
if (!post) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有索引
|
||||
let existed
|
||||
try {
|
||||
existed = await algoliaIndex.getObject(post.id)
|
||||
} catch (error) {
|
||||
// 通常是不存在索引
|
||||
}
|
||||
|
||||
if (existed) {
|
||||
await algoliaIndex
|
||||
.deleteObject(post.id)
|
||||
.wait()
|
||||
.then(r => {
|
||||
console.log('Algolia索引删除成功', r)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('Algolia异常', err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传数据
|
||||
* 根据上次修改文章日期和上次更新索引数据判断是否需要更新algolia索引
|
||||
*/
|
||||
const uploadDataToAlgolia = async post => {
|
||||
// Connect and authenticate with your Algolia app
|
||||
const client = algoliasearch(BLOG.ALGOLIA_APP_ID, BLOG.ALGOLIA_ADMIN_APP_KEY)
|
||||
|
||||
// Create a new index and add a record
|
||||
const index = client.initIndex(BLOG.ALGOLIA_INDEX)
|
||||
|
||||
if (!post) {
|
||||
return
|
||||
}
|
||||
@@ -34,7 +99,7 @@ const uploadDataToAlgolia = async post => {
|
||||
let existed
|
||||
let needUpdateIndex = false
|
||||
try {
|
||||
existed = await index.getObject(post.id)
|
||||
existed = await algoliaIndex.getObject(post.id)
|
||||
} catch (error) {
|
||||
// 通常是不存在索引
|
||||
}
|
||||
@@ -64,7 +129,7 @@ const uploadDataToAlgolia = async post => {
|
||||
content: truncate(getPageContentText(post, post.blockMap), 8192) // 索引8192个字符,API限制总请求内容上限1万个字节
|
||||
}
|
||||
// console.log('更新Algolia索引', record)
|
||||
index
|
||||
algoliaIndex
|
||||
.saveObject(record)
|
||||
.wait()
|
||||
.then(r => {
|
||||
|
||||
@@ -80,28 +80,31 @@ export function convertUrlStartWithOneSlash(str) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是一个相对或绝对路径的ur类
|
||||
* @param {*} str
|
||||
* @returns
|
||||
* 判断是否是一个“URL 样式”的路径(内部或外部)
|
||||
* 内部如 /about,外部如 http://xxx.com
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isUrl(str) {
|
||||
if (!str) {
|
||||
return false
|
||||
}
|
||||
|
||||
return str?.indexOf('/') === 0 || checkStartWithHttp(str)
|
||||
export function isUrlLikePath(str) {
|
||||
return typeof str === 'string' && (str.startsWith('/') || isHttpLink(str))
|
||||
}
|
||||
|
||||
// 检查是否外链
|
||||
export function checkStartWithHttp(str) {
|
||||
// 检查字符串是否包含http
|
||||
if (str?.indexOf('http:') === 0 || str?.indexOf('https:') === 0) {
|
||||
// 如果包含,找到http的位置
|
||||
return true
|
||||
} else {
|
||||
// 不包含
|
||||
return false
|
||||
}
|
||||
/**
|
||||
* 判断是否是 http(s) 开头的链接(外部网页)
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isHttpLink(str) {
|
||||
return typeof str === 'string' && /^https?:\/\//i.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是邮件或电话链接
|
||||
* @param href
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isMailOrTelLink(href) {
|
||||
return /^(mailto:|tel:)/i.test(href)
|
||||
}
|
||||
|
||||
// 检查一个字符串是否UUID https://ihateregex.io/expr/uuid/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 文章相关工具
|
||||
*/
|
||||
import { checkStartWithHttp } from '.'
|
||||
import { isHttpLink } from '.'
|
||||
import { getPostBlocks } from '@/lib/db/getSiteData'
|
||||
import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
@@ -59,7 +59,7 @@ export function checkSlugHasNoSlash(row) {
|
||||
}
|
||||
return (
|
||||
(slug.match(/\//g) || []).length === 0 &&
|
||||
!checkStartWithHttp(slug) &&
|
||||
!isHttpLink(slug) &&
|
||||
row.type.indexOf('Menu') < 0
|
||||
)
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export function checkSlugHasOneSlash(row) {
|
||||
}
|
||||
return (
|
||||
(slug.match(/\//g) || []).length === 1 &&
|
||||
!checkStartWithHttp(slug) &&
|
||||
!isHttpLink(slug) &&
|
||||
row.type.indexOf('Menu') < 0
|
||||
)
|
||||
}
|
||||
@@ -94,7 +94,7 @@ export function checkSlugHasMorThanTwoSlash(row) {
|
||||
return (
|
||||
(slug.match(/\//g) || []).length >= 2 &&
|
||||
row.type.indexOf('Menu') < 0 &&
|
||||
!checkStartWithHttp(slug)
|
||||
!isHttpLink(slug)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { generateRss } from '@/lib/rss'
|
||||
import { generateSitemapXml } from '@/lib/sitemap.xml'
|
||||
import { DynamicLayout } from '@/themes/theme'
|
||||
import { generateRedirectJson } from '@/lib/redirect'
|
||||
import { checkDataFromAlgolia } from '@/lib/plugins/algolia'
|
||||
|
||||
/**
|
||||
* 首页布局
|
||||
@@ -61,6 +62,8 @@ export async function getStaticProps(req) {
|
||||
generateRss(props)
|
||||
// 生成
|
||||
generateSitemapXml(props)
|
||||
// 检查数据是否需要从algolia删除
|
||||
checkDataFromAlgolia(props)
|
||||
if (siteConfig('UUID_REDIRECT', false, props?.NOTION_CONFIG)) {
|
||||
// 生成重定向 JSON
|
||||
generateRedirectJson(props)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
@@ -12,22 +12,22 @@ export default function ArticleAdjacent ({ prev, next }) {
|
||||
}
|
||||
return (
|
||||
<section className='pt-8 text-gray-800 items-center text-xs md:text-sm flex justify-between m-1 '>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/${prev.slug}`}
|
||||
passHref
|
||||
className='py-1 cursor-pointer hover:underline justify-start items-center dark:text-white flex w-full h-full duration-200'>
|
||||
|
||||
<i className='mr-1 fas fa-angle-left' />{prev.title}
|
||||
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={`/${next.slug}`}
|
||||
passHref
|
||||
className='py-1 cursor-pointer hover:underline justify-end items-center dark:text-white flex w-full h-full duration-200'>
|
||||
{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-right' />
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import CONFIG from '../config'
|
||||
@@ -24,9 +24,9 @@ export default function ArticleCopyright() {
|
||||
<ul className='overflow-x-auto whitespace-nowrap text-sm dark:bg-gray-900 bg-gray-100 p-5 leading-8 border-l-2 border-red-500'>
|
||||
<li>
|
||||
<strong className='mr-2'>{locale.COMMON.AUTHOR}:</strong>
|
||||
<Link href={'/about'} className='hover:underline'>
|
||||
<SmartLink href={'/about'} className='hover:underline'>
|
||||
{siteConfig('AUTHOR')}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
<li>
|
||||
<strong className='mr-2'>{locale.COMMON.URL}:</strong>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
@@ -35,7 +35,7 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
: siteInfo?.pageCover
|
||||
|
||||
return (
|
||||
(<Link
|
||||
(<SmartLink
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
@@ -51,7 +51,7 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
<LazyImage src={headerImage} className='absolute top-0 w-full h-full object-cover object-center group-hover:scale-110 group-hover:brightness-50 transform duration-200' />
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
</SmartLink>)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
@@ -29,14 +29,14 @@ const BlogPostArchive = ({ posts = [], archiveTitle }) => {
|
||||
<div id={post?.publishDay}>
|
||||
<span className="text-gray-400">{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
passHref
|
||||
className="dark:text-gray-400 dark:hover:text-red-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
|
||||
{post.title}
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import TagItemMini from './TagItemMini'
|
||||
import TwikooCommentCount from '@/components/TwikooCommentCount'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
@@ -14,7 +14,7 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary
|
||||
return <div className={`flex flex-col justify-between lg:p-6 p-4 ${showPageCover && !showPreview ? 'md:w-7/12 w-full md:max-h-60' : 'w-full'}`}>
|
||||
<div>
|
||||
{/* 标题 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
passHref
|
||||
className={`line-clamp-2 replace cursor-pointer text-2xl ${showPreview ? 'text-center' : ''
|
||||
@@ -22,14 +22,14 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary
|
||||
|
||||
<span className='menu-link '>{post.title}</span>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
{/* 分类 */}
|
||||
{ post?.category && <div
|
||||
className={`flex mt-2 items-center ${showPreview ? 'justify-center' : 'justify-start'
|
||||
} flex-wrap dark:text-gray-500 text-gray-400 `}
|
||||
>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post.category}`}
|
||||
passHref
|
||||
className="cursor-pointer font-light text-sm menu-link hover:text-red-700 dark:hover:text-red-400 transform">
|
||||
@@ -37,7 +37,7 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary
|
||||
<i className="mr-1 far fa-folder" />
|
||||
{post.category}
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
<TwikooCommentCount className='text-sm hover:text-red-700 dark:hover:text-red-400' post={post}/>
|
||||
</div>}
|
||||
@@ -70,7 +70,7 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary
|
||||
{/* 日期标签 */}
|
||||
<div className="text-gray-400 justify-between flex">
|
||||
{/* 日期 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/archive#${formatDate(post?.publishDate, 'yyyy-MM')}`}
|
||||
passHref
|
||||
className="font-light menu-link cursor-pointer text-sm leading-4 mr-3">
|
||||
@@ -78,7 +78,7 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary
|
||||
<i className="far fa-calendar-alt mr-1" />
|
||||
{post?.publishDay || post.lastEditedDay}
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
<div className="md:flex-nowrap flex-wrap md:justify-start inline-block">
|
||||
<div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
if (!categories) {
|
||||
@@ -9,7 +9,7 @@ const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
{categories.map(category => {
|
||||
const selected = currentCategory === category.name
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -20,7 +20,7 @@ const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
|
||||
<div> <i className={`mr-2 fas ${selected ? 'fa-folder-open' : 'fa-folder'}`} />{category.name}({category.count})</div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BeiAnGongAn } from '@/components/BeiAnGongAn'
|
||||
import BeiAnSite from '@/components/BeiAnSite'
|
||||
import CopyRightDate from '@/components/CopyRightDate'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
@@ -40,13 +40,13 @@ const Footer = props => {
|
||||
className={'flex flex-col space-y-2 text-start'}>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${category.name}`}
|
||||
title={`${category.name}`}
|
||||
href={`/category/${category.name}`}
|
||||
passHref>
|
||||
{category.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
@@ -62,13 +62,13 @@ const Footer = props => {
|
||||
className={'flex flex-col space-y-2 text-start'}>
|
||||
{customMenu?.map(menu => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${menu.name}`}
|
||||
title={`${menu.name}`}
|
||||
href={`${menu.href}`}
|
||||
passHref>
|
||||
{menu.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Card from '@/themes/hexo/components/Card'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { RecentComments } from '@waline/client'
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,7 @@ const HexoRecentComments = (props) => {
|
||||
{!onLoading && comments && comments.length > 0 && comments.map((comment) => <div key={comment.objectId} className='pb-2 pl-1'>
|
||||
<div className='dark:text-gray-200 text-sm waline-recent-content wl-content' dangerouslySetInnerHTML={{ __html: comment.comment }} />
|
||||
<div className='dark:text-gray-400 text-gray-400 text-sm text-right cursor-pointer hover:text-red-500 hover:underline pt-1 pr-2'>
|
||||
<Link href={{ pathname: comment.url, hash: comment.objectId, query: { target: 'comment' } }}>--{comment.nick}</Link>
|
||||
<SmartLink href={{ pathname: comment.url, hash: comment.objectId, query: { target: 'comment' } }}>--{comment.nick}</SmartLink>
|
||||
</div>
|
||||
</div>)}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
// import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
const headerImage = post?.pageCoverThumbnail ? post.pageCoverThumbnail : siteInfo?.pageCover
|
||||
|
||||
return (
|
||||
(<Link
|
||||
(<SmartLink
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
@@ -56,7 +56,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
</SmartLink>)
|
||||
)
|
||||
})}
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
// import { siteConfig } from '@/lib/config'
|
||||
import LazyImage from '@/components/LazyImage';
|
||||
|
||||
@@ -11,9 +11,9 @@ export default function LogoBar (props) {
|
||||
const { siteInfo } = props
|
||||
return (
|
||||
<div id='top-wrapper' className='w-full flex items-center'>
|
||||
<Link href='/' className='text-md md:text-xl dark:text-gray-200 r'>
|
||||
<SmartLink href='/' className='text-md md:text-xl dark:text-gray-200 r'>
|
||||
<LazyImage className='h-12 mr-3' src={siteInfo?.icon}/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
{/* <div>{siteConfig('TITLE')}</div> */}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
const MenuGroupCard = props => {
|
||||
@@ -45,7 +45,7 @@ const MenuGroupCard = props => {
|
||||
{links.map(link => {
|
||||
if (link.show) {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${link.slug}`}
|
||||
title={link.name}
|
||||
href={link.href}
|
||||
@@ -57,7 +57,7 @@ const MenuGroupCard = props => {
|
||||
<div className='text-center'>{link.name}</div>
|
||||
<div className='text-center font-semibold'>{link.slot}</div>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ export const MenuItemCollapse = props => {
|
||||
className='w-full px-8 py-3 text-left dark:bg-hexo-black-gray'
|
||||
onClick={toggleShow}>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className='hover:text-[#D2232A] font-extralight flex justify-between pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1'>
|
||||
@@ -40,7 +40,7 @@ export const MenuItemCollapse = props => {
|
||||
{link?.icon && <i className={link.icon + ' mr-4'} />}
|
||||
{link?.name}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
{hasSubMenu && (
|
||||
<div
|
||||
@@ -64,12 +64,12 @@ export const MenuItemCollapse = props => {
|
||||
<div
|
||||
key={index}
|
||||
className='dark:bg-black dark:text-gray-200 text-left px-10 justify-start bg-gray-50 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 py-3 pr-6'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-sm ml-4 whitespace-nowrap'>
|
||||
{link?.icon && <i className={sLink.icon + ' mr-2'} />}{' '}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -22,13 +22,13 @@ export const MenuItemDrop = ({ link }) => {
|
||||
onMouseOut={() => changeShow(false)}
|
||||
className='h-full'>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className={`${selected && 'border-b-2 border-[#D2232A]'} h-full flex space-x-1 whitespace-nowrap items-center font-sans menu-link pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1`}>
|
||||
{link?.icon && <i className={link?.icon} />} <div>{link?.name}</div>
|
||||
{/* {hasSubMenu && <i className='px-2 fa fa-angle-down'></i>} */}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{hasSubMenu && (
|
||||
@@ -50,12 +50,12 @@ export const MenuItemDrop = ({ link }) => {
|
||||
<li
|
||||
key={index}
|
||||
className='cursor-pointer hover:bg-red-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-800 py-1 pr-6 pl-3'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-sm text-nowrap font-extralight'>
|
||||
{link?.icon && <i className={sLink?.icon}> </i>}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 首页导航大按钮组件
|
||||
@@ -15,14 +15,14 @@ const NavButtonGroup = (props) => {
|
||||
<nav id='home-nav-button' className={'w-full z-10 md:h-72 md:mt-6 xl:mt-32 px-5 py-2 mt-8 flex flex-wrap md:max-w-6xl space-y-2 md:space-y-0 md:flex justify-center max-h-80 overflow-auto'}>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${category.name}`}
|
||||
title={`${category.name}`}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
className='text-center shadow-text w-full sm:w-4/5 md:mx-6 md:w-40 md:h-14 lg:h-20 h-14 justify-center items-center flex border-2 cursor-pointer rounded-lg glassmorphism hover:bg-white hover:text-black duration-200 hover:scale-105 transform'>
|
||||
{category.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,7 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
return (
|
||||
<div className="mt-10 mb-5 flex justify-center items-end font-medium text-black duration-500 dark:text-gray-300 py-3 space-x-2">
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: currentPage === 2
|
||||
? `${pagePrefix}/`
|
||||
@@ -30,12 +30,12 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
|
||||
<i className="fas fa-angle-left" />
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
{pages}
|
||||
|
||||
{/* 下一页 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
@@ -45,14 +45,14 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
|
||||
<i className="fas fa-angle-right" />
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getPageElement(page, currentPage, pagePrefix) {
|
||||
return (
|
||||
(<Link
|
||||
(<SmartLink
|
||||
href={page === 1 ? `${pagePrefix}/` : `${pagePrefix}/page/${page}`}
|
||||
key={page}
|
||||
passHref
|
||||
@@ -65,7 +65,7 @@ function getPageElement(page, currentPage, pagePrefix) {
|
||||
|
||||
{page}
|
||||
|
||||
</Link>)
|
||||
</SmartLink>)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
@@ -19,11 +19,11 @@ export default function PostHeader({ post }) {
|
||||
<div className='mt-10'>
|
||||
<div className='mb-3 flex justify-center'>
|
||||
{post.category && <>
|
||||
<Link href={`/category/${post.category}`} passHref legacyBehavior>
|
||||
<SmartLink href={`/category/${post.category}`} passHref legacyBehavior>
|
||||
<div className="cursor-pointer px-2 py-1 mb-2 border rounded-sm dark:border-white text-sm font-medium hover:underline duration-200 shadow-text-md text-white">
|
||||
{post.category}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</>}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
@@ -19,11 +19,11 @@ const ProductCard = ({ index, post, siteInfo }) => {
|
||||
<div key={post.id} className={'group flex flex-col space-y-2 justify-between border dark:border-black bg-white dark:bg-hexo-black-gray'}>
|
||||
|
||||
{/* 图片封面 */}
|
||||
<Link href={`${siteConfig('SUB_PATH', '')}/${post.slug}`} passHref legacyBehavior>
|
||||
<SmartLink href={`${siteConfig('SUB_PATH', '')}/${post.slug}`} passHref legacyBehavior>
|
||||
<div className="overflow-hidden m-2">
|
||||
<LazyImage priority={index === 1} src={post?.pageCoverThumbnail} className='h-auto aspect-square w-full object-cover object-center group-hover:scale-110 duration-500' />
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
<div className='text-center'>{post.title}</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
export default function ProductCategories(props) {
|
||||
@@ -21,14 +21,14 @@ export default function ProductCategories(props) {
|
||||
className={'flex flex-col space-y-2 text-start'}>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${category.name}`}
|
||||
title={`${category.name}`}
|
||||
href={`/category/${category.name}`}
|
||||
className='hover:text-[#D2232A]'
|
||||
passHref>
|
||||
{category.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import Card from './Card'
|
||||
import SearchInput from './SearchInput'
|
||||
@@ -31,7 +31,7 @@ export default function SearchNav(props) {
|
||||
<div id="category-list" className="duration-200 flex flex-wrap mx-8">
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -44,7 +44,7 @@ export default function SearchNav(props) {
|
||||
<i className="mr-4 fas fa-folder" />
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 博客列表上方嵌入条
|
||||
@@ -10,10 +10,10 @@ export default function SlotBar(props) {
|
||||
|
||||
if (tag) {
|
||||
return <div className="cursor-pointer px-3 py-2 mb-4 font-light hover:text-red-700 dark:hover:text-red-400 transform dark:text-white">
|
||||
<Link key={tag} href={`/tag/${encodeURIComponent(tag)}`} passHref
|
||||
<SmartLink key={tag} href={`/tag/${encodeURIComponent(tag)}`} passHref
|
||||
className={'cursor-pointer inline-block rounded duration-200 mr-2 py-0.5 px-1 text-xl whitespace-nowrap '}>
|
||||
<div className='border-b-2 border-[#D2232A] font-light dark:text-gray-400 dark:hover:text-white'> #{tag} </div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
} else if (category) {
|
||||
return <div className="cursor-pointer text-lg px-5 mb-4 font-light hover:text-red-700 dark:hover:text-red-400 transform dark:text-white">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const TagItemMini = ({ tag, selected = false }) => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag}
|
||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
@@ -14,7 +14,7 @@ const TagItemMini = ({ tag, selected = false }) => {
|
||||
|
||||
<div className='font-light'>{selected && <i className='mr-1 fa-tag'/>} {tag.name + (tag.count ? `(${tag.count})` : '')} </div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { isBrowser, scanAndConvertToLinks } from '@/lib/utils'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
@@ -346,7 +346,7 @@ const LayoutCategoryIndex = props => {
|
||||
<div id='category-list' className='duration-200 flex flex-wrap mx-8'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -358,7 +358,7 @@ const LayoutCategoryIndex = props => {
|
||||
<i className='mr-4 fas fa-folder' /> {category.name}(
|
||||
{category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import TwikooCommentCount from '@/components/TwikooCommentCount'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
@@ -20,14 +20,14 @@ const BlogItem = ({ post }) => {
|
||||
className={`${showPageCover ? 'flex md:flex-row flex-col-reverse' : ''} replace mb-12 `}>
|
||||
<div className={`${showPageCover ? 'md:w-7/12' : ''}`}>
|
||||
<h2 className='mb-4'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
className='text-black dark:text-gray-100 text-xl md:text-2xl no-underline hover:underline'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post.pageIcon} />
|
||||
)}
|
||||
{post?.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</h2>
|
||||
|
||||
<div className='mb-4 text-sm text-gray-700 dark:text-gray-300'>
|
||||
@@ -40,11 +40,11 @@ const BlogItem = ({ post }) => {
|
||||
{post.category && (
|
||||
<>
|
||||
<span className='font-bold mx-1'> | </span>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post.category}`}
|
||||
className='text-gray-700 dark:text-gray-300 hover:underline'>
|
||||
{post.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</>
|
||||
)}
|
||||
{/* <span className="font-bold mx-1"> | </span> */}
|
||||
@@ -68,12 +68,12 @@ const BlogItem = ({ post }) => {
|
||||
{/* 图片封面 */}
|
||||
{showPageCover && (
|
||||
<div className='md:w-5/12 w-full h-44 overflow-hidden p-1'>
|
||||
<Link href={post?.href} passHref legacyBehavior>
|
||||
<SmartLink href={post?.href} passHref legacyBehavior>
|
||||
<LazyImage
|
||||
src={post?.pageCoverThumbnail}
|
||||
className='w-full bg-cover hover:scale-110 duration-200'
|
||||
/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
</article>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 博客归档列表;仅归档页面使用
|
||||
@@ -21,11 +21,11 @@ export default function BlogListArchive({ archiveTitle, archivePosts }) {
|
||||
className='border-l-2 p-1 text-xs md:text-base items-center hover:scale-x-105 hover:border-gray-500 dark:hover:border-gray-300 dark:border-gray-400 transform duration-500'>
|
||||
<div id={post?.publishDay}>
|
||||
<span className='text-gray-400'>{post?.publishDay}</span>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
className='dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600'>
|
||||
{post.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import CONFIG from '../config'
|
||||
import BlogItem from './BlogItem'
|
||||
@@ -37,7 +37,7 @@ export const BlogListPage = props => {
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between text-xs'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname:
|
||||
currentPage - 1 === 1
|
||||
@@ -47,15 +47,15 @@ export const BlogListPage = props => {
|
||||
}}
|
||||
className={`${showPrev ? 'bg-black dark:bg-hexo-black-gray' : 'bg-gray pointer-events-none invisible'} text-white no-underline py-2 px-3 rounded`}>
|
||||
{locale.PAGINATION.PREV}
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
className={`${showNext ? 'bg-black dark:bg-hexo-black-gray ' : 'bg-gray pointer-events-none invisible'} text-white no-underline py-2 px-3 rounded`}>
|
||||
{locale.PAGINATION.NEXT}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { MenuList } from './MenuList'
|
||||
|
||||
/**
|
||||
@@ -11,11 +11,11 @@ export const Header = props => {
|
||||
return (
|
||||
<header className='w-full px-6 bg-white dark:bg-black relative z-20'>
|
||||
<div className='mx-auto max-w-4xl md:flex justify-between items-center'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href='/'
|
||||
className='logo py-6 w-full text-center md:text-left md:w-auto text-gray-dark no-underline flex justify-center items-center'>
|
||||
{siteConfig('TITLE')}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<div className='w-full md:w-auto text-center md:text-right'>
|
||||
{/* 右侧文字 */}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -17,10 +17,10 @@ export const MenuItemDrop = ({ link }) => {
|
||||
onMouseOut={() => changeShow(false)}>
|
||||
{!hasSubMenu && (
|
||||
<div className='rounded px-2 md:pl-0 md:mr-3 my-4 md:pr-3 text-gray-700 dark:text-gray-200 no-underline md:border-r border-gray-light'>
|
||||
<Link href={link?.href} target={link?.target}>
|
||||
<SmartLink href={link?.href} target={link?.target}>
|
||||
{link?.icon && <i className={link?.icon} />} {link?.name}
|
||||
{hasSubMenu && <i className='px-2 fa fa-angle-down'></i>}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -41,12 +41,12 @@ export const MenuItemDrop = ({ link }) => {
|
||||
<li
|
||||
key={index}
|
||||
className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-sm text-nowrap font-extralight'>
|
||||
{link?.icon && <i className={sLink?.icon}> </i>}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { formatDateFmt } from '@/lib/utils/formatDate'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
/**
|
||||
* 文章详情的元信息
|
||||
* 标题、作者、分类、标签、创建日期等等。
|
||||
@@ -14,25 +14,25 @@ export const PostMeta = props => {
|
||||
<div>
|
||||
{post?.type !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post?.category}`}
|
||||
passHref
|
||||
className='cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed'>
|
||||
<i className='mr-1 fas fa-folder-open' />
|
||||
{post?.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<span className='mr-2'>|</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
{post?.type !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}
|
||||
passHref
|
||||
className='pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed'>
|
||||
{post?.publishDay}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<span className='mr-2'>|</span>
|
||||
<span className='mx-2 text-gray-400 dark:text-gray-500'>
|
||||
{locale.COMMON.LAST_EDITED_TIME}: {post?.lastEditedDay}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { RecentComments } from '@waline/client'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -44,14 +44,14 @@ const RecentCommentListForExample = props => {
|
||||
dangerouslySetInnerHTML={{ __html: comment.comment }}
|
||||
/>
|
||||
<div className='dark:text-gray-400 text-gray-400 text-sm text-right cursor-pointer hover:text-red-500 hover:underline pt-1'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: comment.url,
|
||||
hash: comment.objectId,
|
||||
query: { target: 'comment' }
|
||||
}}>
|
||||
--{comment.nick}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Live2D from '@/components/Live2D'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import Announcement from './Announcement'
|
||||
import Catalog from './Catalog'
|
||||
@@ -53,7 +53,7 @@ export const SideBar = props => {
|
||||
<ul className='list-reset leading-normal'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -66,7 +66,7 @@ export const SideBar = props => {
|
||||
{category.name}({category.count})
|
||||
</a>
|
||||
</li>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
@@ -83,7 +83,7 @@ export const SideBar = props => {
|
||||
<ul className='list-reset leading-normal'>
|
||||
{latestPosts?.map(p => {
|
||||
return (
|
||||
<Link key={p.id} href={`/${p.slug}`} passHref legacyBehavior>
|
||||
<SmartLink key={p.id} href={`/${p.slug}`} passHref legacyBehavior>
|
||||
<li>
|
||||
{' '}
|
||||
<a
|
||||
@@ -92,7 +92,7 @@ export const SideBar = props => {
|
||||
{p.title}
|
||||
</a>
|
||||
</li>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
import BlogListArchive from './components/BlogListArchive'
|
||||
@@ -292,7 +292,7 @@ const LayoutCategoryIndex = props => {
|
||||
<>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -304,7 +304,7 @@ const LayoutCategoryIndex = props => {
|
||||
<i className='mr-4 fas fa-folder' />
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
@@ -323,7 +323,7 @@ const LayoutTagIndex = props => {
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||
{tagOptions.map(tag => (
|
||||
<div key={tag.name} className='p-2'>
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag}
|
||||
href={`/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
@@ -332,7 +332,7 @@ const LayoutTagIndex = props => {
|
||||
<i className='mr-1 fas fa-tag' />{' '}
|
||||
{tag.name + (tag.count ? `(${tag.count})` : '')}{' '}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 上一篇,下一篇文章
|
||||
@@ -11,22 +11,22 @@ export default function ArticleAround ({ prev, next }) {
|
||||
}
|
||||
return (
|
||||
<section className='text-gray-800 h-28 flex items-center justify-between space-x-5 my-4'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/${prev.slug}`}
|
||||
passHref
|
||||
className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-white bg-opacity-40 hover:bg-hexo-black-gray dark:bg-hexo-black-gray dark:text-gray-200 hover:text-white duration-300'>
|
||||
|
||||
<i className='mr-1 fas fa-angle-double-left' />{prev.title}
|
||||
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={`/${next.slug}`}
|
||||
passHref
|
||||
className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-white bg-opacity-40 hover:bg-hexo-black-gray dark:bg-hexo-black-gray dark:text-gray-200 hover:text-white duration-300'>
|
||||
{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-double-right' />
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import WWAds from '@/components/WWAds'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { formatDateFmt } from '@/lib/utils/formatDate'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import ArticleAround from './ArticleAround'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -55,25 +55,25 @@ export default function ArticleDetail(props) {
|
||||
<div>
|
||||
{post?.category && (
|
||||
<>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post.category}`}
|
||||
passHref
|
||||
className='cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed'>
|
||||
<i className='mr-1 fas fa-folder-open' />
|
||||
{post.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<span className='mr-2'>|</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
{post?.type !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}
|
||||
passHref
|
||||
className='pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed'>
|
||||
{post?.publishDay}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<span className='mr-2'>|</span>
|
||||
<span className='mx-2 text-gray-400 dark:text-gray-500'>
|
||||
{locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedDay}
|
||||
|
||||
@@ -2,7 +2,7 @@ import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -51,7 +51,7 @@ const {siteInfo} =useGlobal()
|
||||
<div className='flex flex-col justify-between h-full'>
|
||||
{/* 封面图 */}
|
||||
{showPageCover && (
|
||||
<Link href={post?.href} passHref legacyBehavior>
|
||||
<SmartLink href={post?.href} passHref legacyBehavior>
|
||||
<div className='flex-grow mb-3 w-full duration-200 cursor-pointer transform overflow-hidden'>
|
||||
<LazyImage
|
||||
src={post?.pageCoverThumbnail}
|
||||
@@ -59,13 +59,13 @@ const {siteInfo} =useGlobal()
|
||||
className='object-cover w-full h-full hover:scale-125 transform duration-500'
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{/* 文字部分 */}
|
||||
<div className='flex flex-col w-full'>
|
||||
<h2>
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
href={post?.href}
|
||||
className={`break-words cursor-pointer font-bold hover:underline text-xl ${showPreview ? 'justify-center' : 'justify-start'} leading-tight text-gray-700 dark:text-gray-100 hover:text-blue-500 dark:hover:text-blue-400`}>
|
||||
@@ -73,7 +73,7 @@ const {siteInfo} =useGlobal()
|
||||
<NotionIcon icon={post.pageIcon} />
|
||||
)}{' '}
|
||||
{post.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</h2>
|
||||
|
||||
{(!showPreview || showSummary) && (
|
||||
@@ -85,13 +85,13 @@ const {siteInfo} =useGlobal()
|
||||
{/* 分类标签 */}
|
||||
<div className='mt-auto justify-between flex'>
|
||||
{post.category && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post.category}`}
|
||||
passHref
|
||||
className='cursor-pointer dark:text-gray-300 font-light text-sm hover:underline hover:text-indigo-700 dark:hover:text-indigo-400 transform'>
|
||||
<i className='mr-1 far fa-folder' />
|
||||
{post.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
<div className='md:flex-nowrap flex-wrap md:justify-start inline-block'>
|
||||
<div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 博客归档
|
||||
@@ -27,12 +27,12 @@ const BlogArchiveItem = ({ posts = [], archiveTitle }) => {
|
||||
<div id={post?.publishDay}>
|
||||
<span className='text-gray-400'>{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
passHref
|
||||
className='dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600'>
|
||||
{post.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
function GroupCategory ({ currentCategory, categories }) {
|
||||
if (!categories) {
|
||||
@@ -10,7 +10,7 @@ function GroupCategory ({ currentCategory, categories }) {
|
||||
{categories.map(category => {
|
||||
const selected = currentCategory === category.name
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -20,7 +20,7 @@ function GroupCategory ({ currentCategory, categories }) {
|
||||
' text-sm w-full items-center duration-300 px-2 cursor-pointer py-1 font-light'}>
|
||||
|
||||
<i className={`${selected ? 'text-white fa-folder-open' : 'fa-folder text-gray-400'} fas mr-2`} />{category.name}({category.count})
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const Logo = props => {
|
||||
return (
|
||||
<section className='flex'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href='/'
|
||||
className='logo hover:bg-black hover:text-white border-black border-2 duration-500 px-4 py-2 cursor-pointer dark:text-gray-300 dark:border-gray-300 font-black'>
|
||||
{siteConfig('TITLE')}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -42,7 +42,7 @@ export const MenuItemCollapse = props => {
|
||||
}
|
||||
onClick={toggleShow}>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className='dark:text-gray-200 py-2 w-full my-auto items-center justify-between flex '>
|
||||
@@ -50,7 +50,7 @@ export const MenuItemCollapse = props => {
|
||||
<div className={`${link.icon} text-center w-4 mr-4`} />
|
||||
{link.name}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{hasSubMenu && (
|
||||
@@ -79,14 +79,14 @@ export const MenuItemCollapse = props => {
|
||||
className='whitespace-nowrap dark:text-gray-200
|
||||
not:last-child:border-b-0 border-b dark:border-gray-800 py-2 px-14 cursor-pointer hover:bg-gray-100
|
||||
font-extralight dark:bg-black text-left justify-start text-gray-600 bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<div>
|
||||
<div
|
||||
className={`${sLink.icon} text-center w-3 mr-3 text-xs`}
|
||||
/>
|
||||
{sLink.title}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const MenuItemDrop = ({ link }) => {
|
||||
@@ -13,7 +13,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
onMouseOut={() => changeShow(false)}
|
||||
className='relative py-1 mb-1.5 duration-500 justify-between text-gray-500 dark:text-gray-300 hover:text-black hover:underline cursor-pointer flex flex-nowrap items-center '>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className='w-full my-auto items-center justify-between flex '>
|
||||
@@ -22,7 +22,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
{link.name}
|
||||
</div>
|
||||
{link.slot}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{hasSubMenu && (
|
||||
@@ -48,7 +48,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
{link?.subMenus?.map((sLink, index) => {
|
||||
return (
|
||||
<li key={index}>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={sLink.href}
|
||||
target={link?.target}
|
||||
className='my-auto py-1 px-2 items-center justify-start flex text-gray-500 dark:text-gray-300 hover:text-black hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 '>
|
||||
@@ -57,7 +57,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
)}
|
||||
<div className={'ml-2 whitespace-nowrap'}>{sLink.name}</div>
|
||||
{sLink.slot}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
export const MenuItemNormal = props => {
|
||||
@@ -9,7 +9,7 @@ export const MenuItemNormal = props => {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${link.href}`}
|
||||
title={link.href}
|
||||
href={link.href}
|
||||
@@ -21,6 +21,6 @@ export const MenuItemNormal = props => {
|
||||
<div className={'hover:text-black'}>{link.name}</div>
|
||||
</div>
|
||||
{link.slot}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
@@ -17,7 +17,7 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
|
||||
return (
|
||||
<div className="my-10 flex justify-between font-medium text-black dark:text-gray-100 space-x-2">
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname:
|
||||
currentPage === 2
|
||||
@@ -32,8 +32,8 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-black border-b-2 hover:font-bold`}>
|
||||
←{locale.PAGINATION.PREV}
|
||||
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
@@ -45,7 +45,7 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-black border-b-2 hover:font-bold`}>
|
||||
|
||||
{locale.PAGINATION.NEXT}→
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
const TagItem = ({ tag, selected }) => {
|
||||
@@ -7,7 +7,7 @@ const TagItem = ({ tag, selected }) => {
|
||||
<div> { locale.COMMON.NOTAG } </div>
|
||||
}
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
@@ -19,7 +19,7 @@ const TagItem = ({ tag, selected }) => {
|
||||
{selected && <i className='mr-1 fas fa-tag'/>} {`${tag.name} `} {tag.count ? `(${tag.count})` : ''}
|
||||
</div>
|
||||
</li>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const TagItemMini = ({ tag, selected = false }) => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag}
|
||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
@@ -14,7 +14,7 @@ const TagItemMini = ({ tag, selected = false }) => {
|
||||
|
||||
<div className='font-light dark:text-gray-400'>{selected && <i className='mr-1 fas fa-tag'/>} {tag.name + (tag.count ? `(${tag.count})` : '')} </div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useGlobal } from '@/lib/global'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useRef } from 'react'
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
@@ -258,7 +258,7 @@ const LayoutCategoryIndex = props => {
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -270,7 +270,7 @@ const LayoutCategoryIndex = props => {
|
||||
<i className='mr-4 fas fa-folder' />
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 归档分组文章
|
||||
@@ -21,12 +21,12 @@ export default function BlogArchiveItem({ archiveTitle, archivePosts }) {
|
||||
<div id={post?.publishDay}>
|
||||
<span className='text-gray-400'>{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
passHref
|
||||
className='dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600'>
|
||||
{post.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@ import NotionIcon from '@/components/NotionIcon'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const BlogPost = ({ post }) => {
|
||||
const { NOTION_CONFIG } = useGlobal()
|
||||
@@ -10,7 +10,7 @@ const BlogPost = ({ post }) => {
|
||||
siteConfig('POST_LIST_PREVIEW', false, NOTION_CONFIG) && post?.blockMap
|
||||
|
||||
return (
|
||||
<Link href={post?.href}>
|
||||
<SmartLink href={post?.href}>
|
||||
<article key={post.id} className='mb-6 md:mb-8'>
|
||||
<header className='flex flex-col justify-between md:flex-row md:items-baseline'>
|
||||
<h2 className='text-lg md:text-xl font-medium mb-2 cursor-pointer text-black dark:text-gray-100'>
|
||||
@@ -37,7 +37,7 @@ const BlogPost = ({ post }) => {
|
||||
)}
|
||||
</main>
|
||||
</article>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { RecentComments } from '@waline/client'
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,7 @@ const ExampleRecentComments = (props) => {
|
||||
{!onLoading && comments && comments.length === 0 && <div>No Comments</div>}
|
||||
{!onLoading && comments && comments.length > 0 && comments.map((comment) => <div key={comment.objectId} className='pb-2'>
|
||||
<div className='dark:text-gray-300 text-gray-600 text-xs waline-recent-content wl-content' dangerouslySetInnerHTML={{ __html: comment.comment }} />
|
||||
<div className='dark:text-gray-400 text-gray-400 text-sm text-right cursor-pointer hover:text-red-500 hover:underline pt-1'><Link href={{ pathname: comment.url, hash: comment.objectId, query: { target: 'comment' } }}>--{comment.nick}</Link></div>
|
||||
<div className='dark:text-gray-400 text-gray-400 text-sm text-right cursor-pointer hover:text-red-500 hover:underline pt-1'><SmartLink href={{ pathname: comment.url, hash: comment.objectId, query: { target: 'comment' } }}>--{comment.nick}</SmartLink></div>
|
||||
</div>)}
|
||||
|
||||
</>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Draggable } from '@/components/Draggable'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { deepClone } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useEffect, useState } from 'react'
|
||||
import DownloadButton from './DownloadButton'
|
||||
import FullScreenButton from './FullScreenButton'
|
||||
@@ -100,12 +100,12 @@ export default function GameEmbed({ post, siteInfo }) {
|
||||
<div
|
||||
style={{ left: '0px', top: '1rem' }}
|
||||
className='text-white fixed xl:hidden group space-x-1 flex items-center z-20 pr-3 pl-1 bg-[#202030] rounded-r-2xl shadow-lg '>
|
||||
<Link
|
||||
<SmartLink
|
||||
href='/'
|
||||
className='px-1 py-3 hover:scale-125 duration-200 transition-all'
|
||||
passHref>
|
||||
<i className='fas fa-chevron-left' />
|
||||
</Link>{' '}
|
||||
</SmartLink>{' '}
|
||||
<span
|
||||
className='font-serif px-1'
|
||||
onClick={() => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { deepClone } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
import CONFIG from '../config'
|
||||
|
||||
@@ -142,7 +142,7 @@ const GameItem = ({ item, isLargeCard }) => {
|
||||
|
||||
const video = item?.ext?.video
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
title={title}
|
||||
href={`${item?.href}`}
|
||||
className={`card-single ${isLargeCard ? 'h-80 ' : 'h-full text-xs'} w-full transition-all duration-200 shadow-md md:hover:scale-105 md:hover:shadow-lg relative rounded-lg overflow-hidden flex justify-center items-center
|
||||
@@ -177,6 +177,6 @@ const GameItem = ({ item, isLargeCard }) => {
|
||||
alt={title}
|
||||
fill='full'
|
||||
/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import { deepClone } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ const GameItem = ({ item }) => {
|
||||
const video = item?.ext?.video
|
||||
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`${item?.href}`}
|
||||
onMouseOver={() => {
|
||||
setShowType('video')
|
||||
@@ -77,6 +77,6 @@ const GameItem = ({ item }) => {
|
||||
src={img}
|
||||
alt={title}
|
||||
/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import { deepClone } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ const GameItem = ({ item }) => {
|
||||
const video = item?.ext?.video
|
||||
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`${item?.href}`}
|
||||
onMouseOver={() => {
|
||||
setShowType('video')
|
||||
@@ -78,6 +78,6 @@ const GameItem = ({ item }) => {
|
||||
src={img}
|
||||
alt={title}
|
||||
/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
function GroupCategory({ currentCategory, categoryOptions }) {
|
||||
if (!categoryOptions) {
|
||||
@@ -7,16 +7,16 @@ function GroupCategory({ currentCategory, categoryOptions }) {
|
||||
|
||||
return (
|
||||
<div className='flex items-center'>
|
||||
<Link className='mx-2' href='/category'>
|
||||
<SmartLink className='mx-2' href='/category'>
|
||||
<i className='fas fa-bars' />
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<div
|
||||
id='category-list'
|
||||
className='dark:border-gray-600 flex flex-wrap py-1'>
|
||||
{categoryOptions.map(category => {
|
||||
const selected = currentCategory === category.name
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -32,7 +32,7 @@ function GroupCategory({ currentCategory, categoryOptions }) {
|
||||
{/* <span className='text-xs flex items-start pl-2 h-full'>
|
||||
{category.count}
|
||||
</span> */}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
/**
|
||||
@@ -12,9 +12,9 @@ function GroupTag({ tagOptions, currentTag }) {
|
||||
if (!tagOptions) return <></>
|
||||
return (
|
||||
<div className='flex items-center'>
|
||||
<Link href='/tag'>
|
||||
<SmartLink href='/tag'>
|
||||
<i className='fas fa-tags p-2' />
|
||||
</Link>
|
||||
</SmartLink>
|
||||
<div id='tags-group' className='flex flex-wrap p-1 gap-2'>
|
||||
{tagOptions?.slice(0, 20)?.map(tag => {
|
||||
const selected = tag.name === currentTag
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/* eslint-disable @next/next/no-html-link-for-pages */
|
||||
export default function Logo({ siteInfo }) {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
href='/'
|
||||
className='logo rounded cursor-pointer flex flex-col items-center'>
|
||||
@@ -16,6 +16,6 @@ export default function Logo({ siteInfo }) {
|
||||
{siteConfig('BIO')}
|
||||
</h2>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/* eslint-disable @next/next/no-html-link-for-pages */
|
||||
export default function LogoMini() {
|
||||
return (
|
||||
<Link href='/' className='logo rounded cursor-pointer flex items-center text-xl text-white font-bold font-serif'>
|
||||
<SmartLink href='/' className='logo rounded cursor-pointer flex items-center text-xl text-white font-bold font-serif'>
|
||||
{siteConfig('TITLE')?.charAt(0)}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ export const MenuItemCollapse = props => {
|
||||
className='w-full px-4 py-2 text-left dark:bg-hexo-black-gray dark:border-black'
|
||||
onClick={toggleShow}>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className='font-extralight flex justify-between pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1'>
|
||||
@@ -44,7 +44,7 @@ export const MenuItemCollapse = props => {
|
||||
)}
|
||||
{link?.name}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
{hasSubMenu && (
|
||||
<div
|
||||
@@ -71,9 +71,9 @@ export const MenuItemCollapse = props => {
|
||||
<div
|
||||
key={index}
|
||||
className='font-extralight dark:bg-black text-left px-10 justify-start bg-gray-50 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 border-b dark:border-gray-800 py-3 pr-6'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-xs'>{sLink.title}</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const MenuItemDrop = ({ link }) => {
|
||||
@@ -17,7 +17,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
onMouseOut={() => changeShow(false)}>
|
||||
{!hasSubMenu && (
|
||||
<div className='dark:text-gray-50 nav hover:scale-105 transition-transform duration-200'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
className='flex flex-nowrap'
|
||||
target={link?.target}>
|
||||
@@ -25,7 +25,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
{link?.icon && <i className={link?.icon} />}
|
||||
</div>
|
||||
{link?.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -47,12 +47,12 @@ export const MenuItemDrop = ({ link }) => {
|
||||
<div
|
||||
key={index}
|
||||
className='text-gray-700 dark:text-gray-200 tracking-widest transition-all duration-200 '>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-sm text-nowrap font-extralight'>
|
||||
{link?.icon && <i className={sLink?.icon}> </i>}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
@@ -21,7 +21,7 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
|
||||
return (
|
||||
<div className='my-10 flex justify-between font-medium text-black dark:text-gray-100 space-x-2'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname:
|
||||
currentPage === 2
|
||||
@@ -35,8 +35,8 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
currentPage === 1 ? 'invisible' : 'visible'
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-black dark:border-hexo-black-gray border-b-2 hover:font-bold`}>
|
||||
←{locale.PAGINATION.PREV}
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
@@ -47,7 +47,7 @@ const PaginationSimple = ({ page, showNext }) => {
|
||||
showNext ? 'visible' : 'invisible'
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-black dark:border-hexo-black-gray border-b-2 hover:font-bold`}>
|
||||
{locale.PAGINATION.NEXT}→
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import TagItem from './TagItem'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
@@ -15,12 +15,12 @@ export default function PostInfo(props) {
|
||||
<div>
|
||||
{post?.type !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${post?.category}`}
|
||||
passHref
|
||||
className='cursor-pointer text-xs font-bold hover:underline mr-2'>
|
||||
{post?.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import dynamic from 'next/dynamic'
|
||||
const ExampleRecentComments = dynamic(() => import('./ExampleRecentComments'))
|
||||
|
||||
@@ -18,13 +18,13 @@ export const SideBar = (props) => {
|
||||
<ul className="list-reset leading-normal">
|
||||
{categories?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<li> <a href="#" className="text-gray-darkest text-sm">{category.name}({category.count})</a></li>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
@@ -39,9 +39,9 @@ export const SideBar = (props) => {
|
||||
<ul className="list-reset leading-normal">
|
||||
{latestPosts?.map(p => {
|
||||
return (
|
||||
<Link key={p.id} href={`/${p.slug}`} passHref legacyBehavior>
|
||||
<SmartLink key={p.id} href={`/${p.slug}`} passHref legacyBehavior>
|
||||
<li> <a href="#" className="text-gray-darkest text-sm">{p.title}</a></li>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const TagItem = ({ tag }) => (
|
||||
<Link href={`/tag/${encodeURIComponent(tag)}`}>
|
||||
<SmartLink href={`/tag/${encodeURIComponent(tag)}`}>
|
||||
<p className='cursor-pointer hover:bg-gray-50 dark:hover:bg-hexo-black-gray mr-1 rounded-full px-2 py-1 border leading-none text-sm dark:border-gray-600'>
|
||||
{tag}
|
||||
</p>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
|
||||
export default TagItem
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const TagItemMini = ({ tag, selected = false }) => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag}
|
||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
className={` rounded hover:text-white hover:bg-green-500 text-black dark:text-white dark:bg-gray-800 py-0.5 px-1 `}
|
||||
@@ -14,7 +14,7 @@ const TagItemMini = ({ tag, selected = false }) => {
|
||||
{tag.count ? `${tag.count}` : ''}
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const Tags = props => {
|
||||
const { tagOptions, tag } = props
|
||||
@@ -19,14 +19,14 @@ const Tags = props => {
|
||||
: 'bg-gray-100 border-gray-100 text-gray-400 dark:bg-night dark:border-gray-800'
|
||||
}`}
|
||||
>
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag.id}
|
||||
href={selected ? '/search' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
className="px-4 py-2 block">
|
||||
|
||||
{`${tag.name} (${tag.count})`}
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { loadWowJS } from '@/lib/plugins/wow'
|
||||
import { deepClone, isBrowser, shuffleArray } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react'
|
||||
import Announcement from './components/Announcement'
|
||||
@@ -400,7 +400,7 @@ const LayoutCategoryIndex = props => {
|
||||
className='duration-200 flex flex-wrap my-4 gap-2'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -412,7 +412,7 @@ const LayoutCategoryIndex = props => {
|
||||
{/* <i className='mr-4 fas fa-folder' /> */}
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
@@ -433,14 +433,14 @@ const LayoutTagIndex = props => {
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap my-4 gap-2'>
|
||||
{tagOptions.map(tag => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag.name}
|
||||
href={`/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
className={` select-none cursor-pointer flex bg-white rounded-lg hover:bg-gray-500 hover:text-white duration-200 mr-2 py-1 px-2 text-xs whitespace-nowrap dark:hover:text-white hover:shadow-xl dark:bg-gray-800`}>
|
||||
<i className='mr-1 fas fa-tag' />{' '}
|
||||
{tag.name + (tag.count ? `(${tag.count})` : '')}{' '}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 上一篇,下一篇文章
|
||||
@@ -15,7 +15,7 @@ export default function ArticleAround({ prev, next }) {
|
||||
|
||||
return (
|
||||
<section className='text-gray-800 dark:text-gray-400 flex items-center justify-between gap-x-3 my-4'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={prev.href}
|
||||
passHref
|
||||
className='rounded border w-full h-20 px-3 cursor-pointer justify-between items-center flex hover:text-green-500 duration-300'>
|
||||
@@ -24,9 +24,9 @@ export default function ArticleAround({ prev, next }) {
|
||||
<div>{locale.COMMON.PREV_POST}</div>
|
||||
<div>{prev.title}</div>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
|
||||
<Link
|
||||
<SmartLink
|
||||
href={next.href}
|
||||
passHref
|
||||
className='rounded border w-full h-20 px-3 cursor-pointer justify-between items-center flex hover:text-green-500 duration-300'>
|
||||
@@ -35,7 +35,7 @@ export default function ArticleAround({ prev, next }) {
|
||||
<div> {next.title}</div>
|
||||
</div>
|
||||
<i className='ml-1 my-1 fas fa-angle-right' />
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
/**
|
||||
* 归档分组
|
||||
@@ -20,12 +20,12 @@ export default function BlogArchiveItem({ archiveTitle, archivePosts }) {
|
||||
<div id={post?.publishDay}>
|
||||
<span className='text-gray-400'>{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
href={post?.href}
|
||||
className='dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600'>
|
||||
{post.title}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Badge from '@/components/Badge'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
const BlogPostCard = ({ post, className }) => {
|
||||
@@ -10,7 +10,7 @@ const BlogPostCard = ({ post, className }) => {
|
||||
decodeURIComponent(router.asPath.split('?')[0]) === post?.href
|
||||
|
||||
return (
|
||||
<Link href={post?.href} passHref>
|
||||
<SmartLink href={post?.href} passHref>
|
||||
<div
|
||||
key={post.id}
|
||||
className={`${className} relative py-1.5 cursor-pointer px-1.5 rounded-md hover:bg-gray-50
|
||||
@@ -26,7 +26,7 @@ const BlogPostCard = ({ post, className }) => {
|
||||
<Badge />
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
export default function CategoryItem ({ selected, category, categoryCount }) {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/category/${category}`}
|
||||
passHref
|
||||
className={(selected
|
||||
@@ -13,6 +13,6 @@ export default function CategoryItem ({ selected, category, categoryCount }) {
|
||||
<div><i className={`mr-2 fas ${selected ? 'fa-folder-open' : 'fa-folder'}`} />{category} {categoryCount && `(${categoryCount})`}
|
||||
</div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
export default function LeftMenuBar () {
|
||||
return (
|
||||
<div className='w-20 border-r hidden lg:block pt-12'>
|
||||
<section>
|
||||
<Link href='/' legacyBehavior>
|
||||
<SmartLink href='/' legacyBehavior>
|
||||
<div className='text-center cursor-pointer hover:text-black'>
|
||||
<i className='fas fa-home text-gray-500'/>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
@@ -12,9 +12,9 @@ export default function LogoBar(props) {
|
||||
const { siteInfo } = props
|
||||
return (
|
||||
<div id='logo-wrapper' className='w-full flex items-center mr-2'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={`/${siteConfig('GITBOOK_INDEX_PAGE', '', CONFIG)}`}
|
||||
className='flex text-lg font-bold md:text-2xl dark:text-gray-200'>
|
||||
className='flex text-lg font-bold md:text-2xl dark:text-gray-200 items-center'>
|
||||
<LazyImage
|
||||
src={siteInfo?.icon}
|
||||
width={24}
|
||||
@@ -23,7 +23,7 @@ export default function LogoBar(props) {
|
||||
className='mr-2 hidden md:block '
|
||||
/>
|
||||
{siteInfo?.title || siteConfig('TITLE')}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -42,7 +42,7 @@ export const MenuItemCollapse = props => {
|
||||
}
|
||||
onClick={toggleShow}>
|
||||
{!hasSubMenu && (
|
||||
<Link
|
||||
<SmartLink
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className='py-2 w-full my-auto items-center justify-between flex '>
|
||||
@@ -50,7 +50,7 @@ export const MenuItemCollapse = props => {
|
||||
<div className={`${link.icon} text-center w-4 mr-4`} />
|
||||
{link.name}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{hasSubMenu && (
|
||||
@@ -79,14 +79,14 @@ export const MenuItemCollapse = props => {
|
||||
className='
|
||||
not:last-child:border-b-0 border-b dark:border-gray-800 py-2 px-14 cursor-pointer hover:bg-gray-100 dark:text-gray-200
|
||||
font-extralight dark:bg-black text-left justify-start text-gray-600 bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<div>
|
||||
<div
|
||||
className={`${sLink.icon} text-center w-3 mr-3 text-xs`}
|
||||
/>
|
||||
{sLink.title}
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -24,9 +24,9 @@ export const MenuItemDrop = ({ link }) => {
|
||||
? 'bg-green-600 text-white hover:text-white'
|
||||
: 'hover:text-green-600')
|
||||
}>
|
||||
<Link href={link?.href} target={link?.target}>
|
||||
<SmartLink href={link?.href} target={link?.target}>
|
||||
{link?.icon && <i className={link?.icon} />} {link?.name}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -56,12 +56,12 @@ export const MenuItemDrop = ({ link }) => {
|
||||
<li
|
||||
key={index}
|
||||
className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
|
||||
<Link href={sLink.href} target={link?.target}>
|
||||
<SmartLink href={sLink.href} target={link?.target}>
|
||||
<span className='text-xs'>
|
||||
{link?.icon && <i className={sLink?.icon}> </i>}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
export const NormalMenu = props => {
|
||||
@@ -12,7 +12,7 @@ export const NormalMenu = props => {
|
||||
const selected = router.pathname === link.href || router.asPath === link.href
|
||||
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={link?.href}
|
||||
title={link.name}
|
||||
href={link.href}
|
||||
@@ -24,6 +24,6 @@ export const NormalMenu = props => {
|
||||
<div className={'hover:text-black'}>{link.name}</div>
|
||||
</div>
|
||||
{link.slot}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
export const MenuItemPCNormal = props => {
|
||||
@@ -10,7 +10,7 @@ export const MenuItemPCNormal = props => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={`${link.id}-${link.slug}`}
|
||||
title={link.name}
|
||||
href={link.href}
|
||||
@@ -25,6 +25,6 @@ export const MenuItemPCNormal = props => {
|
||||
<div className='ml-2 whitespace-nowrap'>{link.name}</div>
|
||||
</div>
|
||||
{link.slot}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
@@ -18,7 +18,7 @@ const PaginationSimple = ({ page, totalPage }) => {
|
||||
|
||||
return (
|
||||
<div className="my-10 flex justify-between font-medium text-black dark:text-gray-100 space-x-2">
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname:
|
||||
currentPage === 2
|
||||
@@ -33,8 +33,8 @@ const PaginationSimple = ({ page, totalPage }) => {
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-green-500 border-b-2 hover:font-bold`}>
|
||||
←{locale.PAGINATION.PREV}
|
||||
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
@@ -46,7 +46,7 @@ const PaginationSimple = ({ page, totalPage }) => {
|
||||
} text-center w-full duration-200 px-4 py-2 hover:border-green-500 border-b-2 hover:font-bold`}>
|
||||
|
||||
{locale.PAGINATION.NEXT}→
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const TagItemMini = ({ tag, selected = false }) => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={tag}
|
||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||
passHref
|
||||
@@ -14,7 +14,7 @@ const TagItemMini = ({ tag, selected = false }) => {
|
||||
|
||||
<div className='font-light dark:text-gray-400'>{selected && <i className='mr-1 fas fa-tag'/>} {tag.name + (tag.count ? `(${tag.count})` : '')} </div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { getShortId } from '@/lib/utils/pageId'
|
||||
import { SignIn, SignUp } from '@clerk/nextjs'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Head from 'next/head'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react'
|
||||
import Announcement from './components/Announcement'
|
||||
@@ -479,7 +479,7 @@ const LayoutCategoryIndex = props => {
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -491,7 +491,7 @@ const LayoutCategoryIndex = props => {
|
||||
<i className='mr-4 fas fa-folder' />
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -44,12 +44,12 @@ const BlogPostArchive = ({ posts = [], archiveTitle, siteInfo }) => {
|
||||
{/* 图片封面 */}
|
||||
{showPageCover && (
|
||||
<div>
|
||||
<Link href={post?.href} passHref legacyBehavior>
|
||||
<SmartLink href={post?.href} passHref legacyBehavior>
|
||||
<LazyImage
|
||||
className={'rounded-xl bg-center bg-cover w-40 h-24'}
|
||||
src={post?.pageCoverThumbnail}
|
||||
/>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -60,24 +60,24 @@ const BlogPostArchive = ({ posts = [], archiveTitle, siteInfo }) => {
|
||||
{post?.category && (
|
||||
<div
|
||||
className={`flex items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-500 text-gray-600 `}>
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
href={`/category/${post.category}`}
|
||||
className='cursor-pointer text-xs font-normal menu-link hover:text-indigo-700 dark:text-gray-600 transform'>
|
||||
{post.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 标题 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
passHref
|
||||
className={
|
||||
' group-hover:text-indigo-700 group-hover:dark:text-indigo-400 text-black dark:text-gray-100 dark:group-hover:text-yellow-600 line-clamp-2 replace cursor-pointer text-xl font-extrabold leading-tight'
|
||||
}>
|
||||
<span className='menu-link '>{post.title}</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
|
||||
{/* 摘要 */}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from './NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import CONFIG from '../config'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -38,7 +38,7 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
}>
|
||||
{/* 图片封面 */}
|
||||
{showPageCover && (
|
||||
<Link href={post?.href} passHref legacyBehavior>
|
||||
<SmartLink href={post?.href} passHref legacyBehavior>
|
||||
<div
|
||||
className={
|
||||
(POST_TWO_COLS ? ' 2xl:w-full' : '') +
|
||||
@@ -51,7 +51,7 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
className='h-full w-full object-cover group-hover:scale-105 group-hover:brightness-75 transition-all duration-500 ease-in-out' //宽高都调整为自适应,保证封面居中
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)}
|
||||
|
||||
{/* 文字区块 */}
|
||||
@@ -65,17 +65,17 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
{post?.category && (
|
||||
<div
|
||||
className={`flex mb-1 items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-300 text-gray-600 hover:text-indigo-700 dark:hover:text-yellow-500`}>
|
||||
<Link
|
||||
<SmartLink
|
||||
passHref
|
||||
href={`/category/${post.category}`}
|
||||
className='cursor-pointer text-xs font-normal menu-link '>
|
||||
{post.category}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 标题和图标 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={post?.href}
|
||||
passHref
|
||||
className={
|
||||
@@ -88,7 +88,7 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
/>
|
||||
)}
|
||||
<span className='menu-link '>{post.title}</span>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</header>
|
||||
|
||||
{/* 摘要 */}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChevronDoubleLeft, ChevronDoubleRight } from '@/components/HeroIcons'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
@@ -55,11 +55,11 @@ export default function CategoryBar(props) {
|
||||
<ChevronDoubleRight className={'w-5 h-5'} />
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
<SmartLink
|
||||
href='/category'
|
||||
className='whitespace-nowrap font-bold text-gray-900 dark:text-white transition-colors duration-200 hover:text-indigo-600 dark:hover:text-yellow-600'>
|
||||
{locale.MENU.CATEGORY}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -77,7 +77,7 @@ const MenuItem = ({ href, name }) => {
|
||||
return (
|
||||
<div
|
||||
className={`whitespace-nowrap mr-2 duration-200 transition-all font-bold px-2 py-0.5 rounded-md text-gray-900 dark:text-white hover:text-white hover:bg-indigo-600 dark:hover:bg-yellow-600 ${selected ? 'text-white bg-indigo-600 dark:bg-yellow-600' : ''}`}>
|
||||
<Link href={href}>{name}</Link>
|
||||
<SmartLink href={href}>{name}</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
|
||||
const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
if (!categories) {
|
||||
@@ -9,7 +9,7 @@ const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
{categories.map(category => {
|
||||
const selected = currentCategory === category.name
|
||||
return (
|
||||
<Link
|
||||
<SmartLink
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
passHref
|
||||
@@ -20,7 +20,7 @@ const CategoryGroup = ({ currentCategory, categories }) => {
|
||||
|
||||
<div> <i className={`mr-2 fas ${selected ? 'fa-folder-open' : 'fa-folder'}`} />{category.name}({category.count})</div>
|
||||
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ArrowSmallRight, PlusSmall } from '@/components/HeroIcons'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useImperativeHandle, useRef, useState } from 'react'
|
||||
import CONFIG from '../config'
|
||||
@@ -176,7 +176,7 @@ function GroupMenu() {
|
||||
|
||||
return (
|
||||
<div className='h-[165px] select-none xl:h-20 flex flex-col justify-between xl:space-y-0 xl:flex-row w-28 lg:w-48 xl:w-full xl:flex-nowrap xl:space-x-3'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={url_1}
|
||||
className='group relative overflow-hidden bg-gradient-to-r from-blue-500 to-blue-400 flex h-20 justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
|
||||
<div className='font-bold lg:text-lg pl-5 relative -mt-2'>
|
||||
@@ -186,8 +186,8 @@ function GroupMenu() {
|
||||
<div className='hidden lg:block absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>
|
||||
<i className='fa-solid fa-star text-4xl'></i>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
</SmartLink>
|
||||
<SmartLink
|
||||
href={url_2}
|
||||
className='group relative overflow-hidden bg-gradient-to-r from-red-500 to-yellow-500 flex h-20 justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
|
||||
<div className='font-bold lg:text-lg pl-5 relative -mt-2'>
|
||||
@@ -197,9 +197,9 @@ function GroupMenu() {
|
||||
<div className='hidden lg:block absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>
|
||||
<i className='fa-solid fa-fire-flame-curved text-4xl'></i>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
{/* 第三个标签在小屏上不显示 */}
|
||||
<Link
|
||||
<SmartLink
|
||||
href={url_3}
|
||||
className='group relative overflow-hidden bg-gradient-to-r from-teal-300 to-cyan-300 hidden h-20 xl:flex justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
|
||||
<div className='font-bold text-lg pl-5 relative -mt-2'>
|
||||
@@ -209,7 +209,7 @@ function GroupMenu() {
|
||||
<div className='absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>
|
||||
<i className='fa-solid fa-book-bookmark text-4xl '></i>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -239,7 +239,7 @@ function TopGroup(props) {
|
||||
className='w-full flex space-x-3 xl:space-x-0 xl:grid xl:grid-cols-3 xl:gap-3 xl:h-[342px]'>
|
||||
{topPosts?.map((p, index) => {
|
||||
return (
|
||||
<Link href={`${siteConfig('SUB_PATH', '')}/${p?.slug}`} key={index}>
|
||||
<SmartLink href={`${siteConfig('SUB_PATH', '')}/${p?.slug}`} key={index}>
|
||||
<div className='cursor-pointer h-[164px] group relative flex flex-col w-52 xl:w-full overflow-hidden shadow bg-white dark:bg-black dark:text-white rounded-xl'>
|
||||
<LazyImage
|
||||
priority={index === 0}
|
||||
@@ -255,7 +255,7 @@ function TopGroup(props) {
|
||||
{locale.COMMON.RECOMMEND_BADGES}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</SmartLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { RecentComments } from '@waline/client'
|
||||
import Link from 'next/link'
|
||||
import SmartLink from '@/components/SmartLink'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
/**
|
||||
@@ -49,14 +49,14 @@ const HexoRecentComments = props => {
|
||||
dangerouslySetInnerHTML={{ __html: comment.comment }}
|
||||
/>
|
||||
<div className='dark:text-gray-400 text-gray-400 text-sm text-right cursor-pointer hover:text-red-500 hover:underline pt-1 pr-2'>
|
||||
<Link
|
||||
<SmartLink
|
||||
href={{
|
||||
pathname: comment.url,
|
||||
hash: comment.objectId,
|
||||
query: { target: 'comment' }
|
||||
}}>
|
||||
--{comment.nick}
|
||||
</Link>
|
||||
</SmartLink>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user