mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 23:16:49 +00:00
@@ -1,2 +1,2 @@
|
||||
# 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables
|
||||
NEXT_PUBLIC_VERSION=3.6.5
|
||||
NEXT_PUBLIC_VERSION=3.6.6
|
||||
@@ -14,7 +14,7 @@ import { isIterable } from '../utils'
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export function getAllCategories({ allPages, categoryOptions, sliceCount = 0 }) {
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
const allPosts = allPages.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
if (!allPosts || !categoryOptions) {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { isIterable } from '../utils'
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export function getAllTags({ allPages, sliceCount = 0, tagOptions }) {
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
const allPosts = allPages.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
|
||||
if (!allPosts || !tagOptions) {
|
||||
return []
|
||||
|
||||
@@ -212,17 +212,16 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
collectionData.push(properties)
|
||||
}
|
||||
}
|
||||
// 读取映射 配置
|
||||
let postCount = 0
|
||||
|
||||
// 获取page作为自定义菜单
|
||||
const customNav = getCustomNav({ allPages: collectionData.filter(post => post.type === 'Page' && post.status === 'Published') })
|
||||
|
||||
// 文章计数
|
||||
let postCount = 0
|
||||
const allPages = collectionData.filter(post => {
|
||||
if (post.type === 'Post' && post.status === 'Published') {
|
||||
postCount++
|
||||
}
|
||||
|
||||
return post &&
|
||||
post.type &&
|
||||
(post.type === 'Post' || post.type === 'Page') &&
|
||||
|
||||
@@ -3,6 +3,7 @@ import { NotionAPI } from 'notion-client'
|
||||
import BLOG from '@/blog.config'
|
||||
import formatDate from '../formatDate'
|
||||
import { defaultMapImageUrl } from 'react-notion-x'
|
||||
import md5 from 'js-md5'
|
||||
|
||||
export default async function getPageProperties(id, block, schema, authToken, tagOptions, siteInfo) {
|
||||
const rawProperties = Object.entries(block?.[id]?.value?.properties || [])
|
||||
@@ -89,6 +90,7 @@ export default async function getPageProperties(id, block, schema, authToken, ta
|
||||
properties.pageIcon = getImageUrl(block[id].value?.format?.page_icon, block[id].value) ?? ''
|
||||
properties.page_cover = getImageUrl(block[id].value?.format?.page_cover, block[id].value) ?? siteInfo?.pageCover
|
||||
properties.content = value.content ?? []
|
||||
properties.password = properties.password ? md5(properties.slug + properties.password) : ''
|
||||
properties.tagItems = properties?.tags?.map(tag => {
|
||||
return { name: tag, color: tagOptions?.find(t => t.value === tag)?.color || 'gray' }
|
||||
}) || []
|
||||
|
||||
90
lib/notion/getPageTableOfContents.js
Normal file
90
lib/notion/getPageTableOfContents.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { getTextContent } from 'notion-utils'
|
||||
|
||||
const indentLevels = {
|
||||
header: 0,
|
||||
sub_header: 1,
|
||||
sub_sub_header: 2
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/NotionX/react-notion-x/blob/master/packages/notion-utils/src/get-page-table-of-contents.ts
|
||||
* Gets the metadata for a table of contents block by parsing the page's
|
||||
* H1, H2, and H3 elements.
|
||||
*/
|
||||
export const getPageTableOfContents = (page, recordMap) => {
|
||||
const contents = (page.content ?? [])
|
||||
const toc = getBlockHeader(contents, recordMap)
|
||||
const indentLevelStack = [
|
||||
{
|
||||
actual: -1,
|
||||
effective: -1
|
||||
}
|
||||
]
|
||||
|
||||
// Adjust indent levels to always change smoothly.
|
||||
// This is a little tricky, but the key is that when increasing indent levels,
|
||||
// they should never jump more than one at a time.
|
||||
for (const tocItem of toc) {
|
||||
const { indentLevel } = tocItem
|
||||
const actual = indentLevel
|
||||
|
||||
do {
|
||||
const prevIndent = indentLevelStack[indentLevelStack.length - 1]
|
||||
const { actual: prevActual, effective: prevEffective } = prevIndent
|
||||
|
||||
if (actual > prevActual) {
|
||||
tocItem.indentLevel = prevEffective + 1
|
||||
indentLevelStack.push({
|
||||
actual,
|
||||
effective: tocItem.indentLevel
|
||||
})
|
||||
} else if (actual === prevActual) {
|
||||
tocItem.indentLevel = prevEffective
|
||||
break
|
||||
} else {
|
||||
indentLevelStack.pop()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
} while (true)
|
||||
}
|
||||
|
||||
return toc
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写获取目录方法
|
||||
*/
|
||||
function getBlockHeader(contents, recordMap, toc) {
|
||||
if (!toc) {
|
||||
toc = []
|
||||
}
|
||||
if (!contents) {
|
||||
return toc
|
||||
}
|
||||
|
||||
for (const blockId of contents) {
|
||||
const block = recordMap.block[blockId]?.value
|
||||
if (!block) {
|
||||
continue
|
||||
}
|
||||
const { type } = block
|
||||
if (type.indexOf('header') >= 0) {
|
||||
const existed = toc.find(e => e.id === blockId)
|
||||
if (!existed) {
|
||||
toc.push({
|
||||
id: blockId,
|
||||
type,
|
||||
text: getTextContent(block.properties?.title),
|
||||
indentLevel: indentLevels[type]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (block.content?.length > 0) {
|
||||
getBlockHeader(block.content, recordMap, toc)
|
||||
}
|
||||
}
|
||||
|
||||
return toc
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "notion-next",
|
||||
"version": "3.6.5",
|
||||
"version": "3.6.6",
|
||||
"homepage": "https://github.com/tangly1024/NotionNext.git",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -30,6 +30,7 @@
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"feed": "^4.2.2",
|
||||
"gitalk": "^1.7.2",
|
||||
"js-md5": "^0.7.3",
|
||||
"localStorage": "^1.0.4",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mark.js": "^8.11.1",
|
||||
|
||||
@@ -8,6 +8,8 @@ import { idToUuid } from 'notion-utils'
|
||||
import Router from 'next/router'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { getNotion } from '@/lib/notion/getNotion'
|
||||
import md5 from 'js-md5'
|
||||
import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents'
|
||||
|
||||
/**
|
||||
* 根据notion的slug访问页面
|
||||
@@ -28,6 +30,11 @@ const Slug = props => {
|
||||
if (post?.password && post?.password !== '') {
|
||||
setLock(true)
|
||||
} else {
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
setLock(false)
|
||||
}
|
||||
}, [post])
|
||||
@@ -51,10 +58,12 @@ const Slug = props => {
|
||||
* 验证文章密码
|
||||
* @param {*} result
|
||||
*/
|
||||
const validPassword = result => {
|
||||
if (result) {
|
||||
const validPassword = passInput => {
|
||||
if (passInput && md5(post.slug + passInput) === post.password) {
|
||||
setLock(false)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
props = { ...props, lock, setLock, validPassword }
|
||||
|
||||
@@ -191,4 +191,15 @@ nav {
|
||||
|
||||
.wl-meta > span {
|
||||
@apply dark:bg-gray-800 !important
|
||||
}
|
||||
|
||||
/* 固定两行 */
|
||||
.text-line-2 {
|
||||
overflow : hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -392,7 +392,7 @@
|
||||
|
||||
.notion-h {
|
||||
position: relative;
|
||||
display: block;
|
||||
/* display: block; */
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
padding: 3px 2px;
|
||||
@@ -427,7 +427,7 @@
|
||||
margin-top: 2px;
|
||||
} */
|
||||
.notion-h2 {
|
||||
font-size: 1.5em;
|
||||
font-size: 1.4em;
|
||||
margin-top: 1.1em;
|
||||
}
|
||||
.notion-h3 {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import LayoutBase from './LayoutBase'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
@@ -12,15 +11,10 @@ export const LayoutSlug = props => {
|
||||
return <LayoutBase {...props} />
|
||||
}
|
||||
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
|
||||
{lock && <ArticleLock password={post.password} validPassword={validPassword} />}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
{!lock && <div id="notion-article" className="px-2">
|
||||
|
||||
|
||||
@@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global'
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
const { password, validPassword } = props
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
if (p && p.value && p.value === password) {
|
||||
validPassword(true)
|
||||
} else {
|
||||
if (!validPassword(p?.value)) {
|
||||
const tips = document.getElementById('tips')
|
||||
if (tips) {
|
||||
tips.innerHTML = ''
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
import LayoutBase from './LayoutBase'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
|
||||
export const LayoutSlug = (props) => {
|
||||
const { post, lock, validPassword } = props
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
const { lock, validPassword } = props
|
||||
return (
|
||||
<LayoutBase {...props} >
|
||||
{!lock && <ArticleDetail {...props} />}
|
||||
{lock && <ArticleLock password={post.password} validPassword={validPassword} />}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
</LayoutBase>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global'
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
const { password, validPassword } = props
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
if (p && p.value && p.value === password) {
|
||||
validPassword(true)
|
||||
} else {
|
||||
if (!validPassword(p?.value)) {
|
||||
const tips = document.getElementById('tips')
|
||||
if (tips) {
|
||||
tips.innerHTML = ''
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import { useRef } from 'react'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import HeaderArticle from './components/HeaderArticle'
|
||||
@@ -15,6 +14,7 @@ import { isBrowser } from '@/lib/utils'
|
||||
|
||||
export const LayoutSlug = props => {
|
||||
const { post, lock, validPassword } = props
|
||||
const drawerRight = useRef(null)
|
||||
|
||||
if (!post) {
|
||||
return <LayoutBase
|
||||
@@ -25,12 +25,6 @@ export const LayoutSlug = props => {
|
||||
></LayoutBase>
|
||||
}
|
||||
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
const drawerRight = useRef(null)
|
||||
const targetRef = isBrowser() ? document.getElementById('container') : null
|
||||
|
||||
const floatSlot = <>
|
||||
@@ -53,7 +47,7 @@ export const LayoutSlug = props => {
|
||||
floatSlot={floatSlot}
|
||||
>
|
||||
<div className="w-full lg:shadow-sm lg:hover:shadow lg:border lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">
|
||||
{lock && <ArticleLock password={post.password} validPassword={validPassword} />}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
{!lock && <div id="container" className="overflow-x-auto flex-grow mx-auto md:w-full md:px-5 ">
|
||||
|
||||
|
||||
@@ -8,13 +8,11 @@ import { useGlobal } from '@/lib/global'
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
const { password, validPassword } = props
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
if (p && p.value && p.value === password) {
|
||||
validPassword(true)
|
||||
} else {
|
||||
if (!validPassword(p?.value)) {
|
||||
const tips = document.getElementById('tips')
|
||||
if (tips) {
|
||||
tips.innerHTML = ''
|
||||
|
||||
@@ -4,12 +4,13 @@ import formatDate from '@/lib/formatDate'
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
export default function HeaderArticle({ post, siteInfo }) {
|
||||
const { locale } = useGlobal()
|
||||
|
||||
if (!post) {
|
||||
return <></>
|
||||
}
|
||||
const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("${siteInfo?.pageCover}")`
|
||||
|
||||
const { locale } = useGlobal()
|
||||
const date = formatDate(
|
||||
post?.date?.start_date || post?.createdTime,
|
||||
locale.LOCALE
|
||||
|
||||
@@ -10,12 +10,14 @@ import { useRouter } from 'next/router'
|
||||
* @constructor
|
||||
*/
|
||||
const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
// 获取当前路径
|
||||
const currentPath = useRouter().asPath
|
||||
const { locale } = useGlobal()
|
||||
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=" mb-2 px-1 flex flex-nowrap justify-between">
|
||||
@@ -37,7 +39,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a className={'my-1 flex '}>
|
||||
<a className={'my-2 flex'}>
|
||||
<div
|
||||
className="w-20 h-16 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
@@ -45,12 +47,12 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
<div
|
||||
className={
|
||||
(selected ? ' text-indigo-400 ' : 'dark:text-gray-400 ') +
|
||||
' text-sm py-1.5 overflow-x-hidden hover:text-indigo-600 px-2 duration-200 w-full rounded ' +
|
||||
' text-sm overflow-x-hidden hover:text-indigo-600 px-2 duration-200 w-full rounded ' +
|
||||
'hover:text-white dark:hover:text-indigo-400 cursor-pointer items-center flex'
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<div style={{ WebkitLineClamp: 2 }}>{post.title}</div>
|
||||
<div className='text-line-2'>{post.title}</div>
|
||||
<div className="text-gray-500">{post.lastEditedTime}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import BLOG from '@/blog.config'
|
||||
|
||||
export const LayoutCategory = props => {
|
||||
const { category } = props
|
||||
const slotTop = <div className='flex items-center font-sans p-8'><div className='text-xl'><i className='mr-2 fas fa-th' />分类:</div>{category}</div>
|
||||
const slotTop = <div className='flex items-center font-sans py-8'><div className='text-xl'><i className='mr-2 fas fa-th' />分类:</div>{category}</div>
|
||||
|
||||
return <LayoutBase {...props} slotTop={slotTop}>
|
||||
{BLOG.POST_LIST_STYLE === 'page' ? <BlogPostListPage {...props} /> : <BlogPostListScroll {...props} />}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
|
||||
import LayoutBase from './LayoutBase'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import React from 'react'
|
||||
@@ -16,11 +14,6 @@ export const LayoutSlug = props => {
|
||||
/>
|
||||
}
|
||||
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
const slotRight = post?.toc && post?.toc?.length > 3 && (
|
||||
<div key={locale.COMMON.TABLE_OF_CONTENTS} >
|
||||
<Catalog toc={post.toc} />
|
||||
@@ -29,7 +22,7 @@ export const LayoutSlug = props => {
|
||||
|
||||
return (
|
||||
<LayoutBase showInfoCard={true} slotRight={slotRight} {...props} >
|
||||
{!lock ? <ArticleDetail {...props} /> : <ArticleLock password={post.password} validPassword={validPassword} />}
|
||||
{!lock ? <ArticleDetail {...props} /> : <ArticleLock validPassword={validPassword} />}
|
||||
</LayoutBase>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import BlogPostListPage from './components/BlogPostListPage'
|
||||
|
||||
export const LayoutTag = (props) => {
|
||||
const { tag } = props
|
||||
const slotTop = <div className='flex items-center font-sans p-8'><div className='text-xl'><i className='mr-2 fas fa-tag'/>标签:</div>{tag}</div>
|
||||
const slotTop = <div className='flex items-center font-sans py-8'><div className='text-xl'><i className='mr-2 fas fa-tag'/>标签:</div>{tag}</div>
|
||||
|
||||
return <LayoutBase {...props} slotTop={slotTop}>
|
||||
{BLOG.POST_LIST_STYLE === 'page' ? <BlogPostListPage {...props} /> : <BlogPostListScroll {...props} />}
|
||||
|
||||
@@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global'
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
const { password, validPassword } = props
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
if (p && p.value && p.value === password) {
|
||||
validPassword(true)
|
||||
} else {
|
||||
if (!validPassword(p?.value)) {
|
||||
const tips = document.getElementById('tips')
|
||||
if (tips) {
|
||||
tips.innerHTML = ''
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import TocDrawerButton from './components/TocDrawerButton'
|
||||
import LayoutBase from './LayoutBase'
|
||||
import Card from './components/Card'
|
||||
@@ -12,11 +11,6 @@ import { isBrowser } from '@/lib/utils'
|
||||
|
||||
export const LayoutSlug = (props) => {
|
||||
const { post, latestPosts, lock, validPassword } = props
|
||||
if (!lock && post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
const drawerRight = useRef(null)
|
||||
const targetRef = isBrowser() ? document.getElementById('container') : null
|
||||
const floatSlot = post?.toc?.length > 1
|
||||
@@ -45,7 +39,7 @@ export const LayoutSlug = (props) => {
|
||||
|
||||
{!lock && <ArticleDetail {...props} />}
|
||||
|
||||
{lock && <ArticleLock password={post.password} validPassword={validPassword} />}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
{/* 悬浮目录按钮 */}
|
||||
<div className='block lg:hidden'>
|
||||
|
||||
@@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global'
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
const { password, validPassword } = props
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
if (p && p.value && p.value === password) {
|
||||
validPassword(true)
|
||||
} else {
|
||||
if (!validPassword(p?.value)) {
|
||||
const tips = document.getElementById('tips')
|
||||
if (tips) {
|
||||
tips.innerHTML = ''
|
||||
|
||||
@@ -10,13 +10,14 @@ import { useRouter } from 'next/router'
|
||||
* @constructor
|
||||
*/
|
||||
const LatestPostsGroup = ({ latestPosts }) => {
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
// 获取当前路径
|
||||
const currentPath = useRouter().asPath
|
||||
const { locale } = useGlobal()
|
||||
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="text-sm pb-1 px-2 flex flex-nowrap justify-between">
|
||||
@@ -40,12 +41,11 @@ const LatestPostsGroup = ({ latestPosts }) => {
|
||||
(selected
|
||||
? 'text-white bg-gray-600 '
|
||||
: 'text-gray-500 dark:text-gray-400 ') +
|
||||
' text-xs py-1.5 flex overflow-x-hidden whitespace-nowrap hover:bg-gray-500 px-2 duration-200 w-full ' +
|
||||
' text-xs py-1.5 flex hover:bg-gray-500 px-2 duration-200 w-full ' +
|
||||
'hover:text-white dark:hover:text-white cursor-pointer'
|
||||
}
|
||||
>
|
||||
<i className="mr-2 fas fa-file-alt" />
|
||||
<div className="truncate">{post.title}</div>
|
||||
<li className="text-line-2">{post.title}</li>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
Reference in New Issue
Block a user