refactor: add missing information of articles

This commit is contained in:
jinhojang6 2023-05-08 18:10:40 +09:00
parent 8779020f7f
commit 31819407c8
No known key found for this signature in database
GPG Key ID: 0E7AA62CB0D9E6F3
5 changed files with 95 additions and 51 deletions

View File

@ -11,17 +11,15 @@ import { moreFromAuthor, references, relatedArticles } from './tempData'
import { ArticleReference } from '../ArticleReference'
export default function Article({
appearance: {
size = PostSize.SMALL,
aspectRatio = PostImageRatio.LANDSCAPE,
} = {},
appearance: { aspectRatio = PostImageRatio.LANDSCAPE } = {},
data: {
coverImage = null,
date: dateStr = '',
title,
text,
blocks,
summary,
author,
authorEmail,
tags = [],
toc = [],
},
@ -42,19 +40,17 @@ export default function Article({
)
}, [coverImage])
const _text = useMemo(
() => (
<CustomTypography variant="body1" genericFontFamily="sans-serif">
{text}
</CustomTypography>
),
[text],
// TODO : using typography for the blocks
const _blocks = useMemo(
() => <Blocks dangerouslySetInnerHTML={{ __html: blocks ?? '' }} />,
[blocks],
)
const _mobileToc = useMemo(
() =>
toc?.length > 0 && (
<Collapse className={styles.mobileToc} label="Contents">
{/* @ts-ignore */}
{toc.map((toc, idx) => (
<Content
onClick={() => setTocIndex(idx)}
@ -136,19 +132,13 @@ export default function Article({
</Row>
</div>
<CustomTypography
variant={size === PostSize.SMALL ? 'h4' : 'h2'}
genericFontFamily="serif"
>
<Title variant={'h1'} genericFontFamily="serif">
{title}
</CustomTypography>
</Title>
{_thumbnail}
<CustomTypography
variant={size === PostSize.SMALL ? 'h4' : 'h2'}
genericFontFamily="serif"
>
<CustomTypography variant={'body1'} genericFontFamily="sans-serif">
{summary}
</CustomTypography>
@ -162,20 +152,34 @@ export default function Article({
</TagContainer>
)}
<Typography variant="body3" genericFontFamily="sans-serif">
{author}
</Typography>
<AuthorInfo>
<Typography
variant="body3"
component="p"
genericFontFamily="sans-serif"
>
{author}
</Typography>
<Typography
href={`mailto:${authorEmail}`}
variant="body3"
component="a"
genericFontFamily="sans-serif"
>
{authorEmail}
</Typography>
</AuthorInfo>
{_mobileToc}
{_text}
{_blocks}
{_references}
<div>
<ArticleReferences>
{_moreFromAuthor}
{_relatedArticles}
</div>
</ArticleReferences>
</ArticleContainer>
)
}
@ -195,6 +199,22 @@ const ArticleContainer = styled.article`
}
`
const CustomTypography = styled(Typography)`
text-overflow: ellipsis;
word-break: break-word;
white-space: pre-wrap;
`
const Title = styled(CustomTypography)`
margin-bottom: 24px;
`
const Blocks = styled.div`
white-space: pre-wrap;
margin-top: 24px;
margin-bottom: 80px;
`
const ThumbnailContainer = styled.div<{
aspectRatio: PostImageRatio
}>`
@ -219,16 +239,9 @@ const Row = styled.div`
gap: 8px;
margin-bottom: 8px;
`
const CustomTypography = styled(Typography)`
text-overflow: ellipsis;
word-break: break-word;
white-space: pre-wrap;
`
const TagContainer = styled.div`
display: flex;
gap: 8px;
overflow-x: auto;
`
const Content = styled(CustomTypography)<{ active: boolean }>`
@ -248,3 +261,14 @@ const Reference = styled.div`
padding: 8px 14px;
gap: 8px;
`
const ArticleReferences = styled.div`
margin-top: 16px;
`
const AuthorInfo = styled.div`
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 8px;
`

View File

@ -4,7 +4,11 @@ import styled from '@emotion/styled'
import Image from 'next/image'
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
import { useMemo } from 'react'
import { UnbodyImageBlock } from '@/lib/unbody/unbody.types'
import {
UnbodyGoogleDoc,
UnbodyImageBlock,
UnbodyTextBlock,
} from '@/lib/unbody/unbody.types'
export enum PostImageRatio {
PORTRAIT = 'portrait',
@ -46,11 +50,12 @@ export type PostDataProps = {
title: string
description?: string
author?: string
authorEmail?: string // TODO: can we get author: { name: string, email: string }?
tags?: string[]
coverImage?: UnbodyImageBlock | null
summary?: string
text?: string
toc?: string[]
blocks?: UnbodyTextBlock
toc?: Pick<UnbodyGoogleDoc, 'toc'>['toc']
}
export const PostImageRatioOptions = {

View File

@ -3,9 +3,12 @@ import { useArticleContainerContext } from '@/containers/ArticleContainer.Contex
import { useSticky } from '@/utils/ui.utils'
import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
import { UnbodyGoogleDoc } from '@/lib/unbody/unbody.types'
export type TableOfContentsProps = Pick<UnbodyGoogleDoc, 'toc'>
type Props = {
contents: string[]
contents?: TableOfContentsProps['toc']
}
export default function TableOfContents({ contents, ...props }: Props) {
@ -16,8 +19,14 @@ export default function TableOfContents({ contents, ...props }: Props) {
const { sticky, stickyRef, height } = useSticky<HTMLDivElement>(dy)
const handleSectionClick = (index: number) => {
//@ts-ignore
const section = document.getElementById(contents[index].href.substring(1))
section?.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'nearest',
})
setTocIndex(index)
// TODO: scrollIntoView
}
return (
@ -29,14 +38,15 @@ export default function TableOfContents({ contents, ...props }: Props) {
className={sticky ? 'sticky' : ''}
>
<Title variant="body3">Contents</Title>
{contents.map((content, index) => (
{/* @ts-ignore */}
{contents?.map((content, index) => (
<Section
active={index === tocIndex}
onClick={() => handleSectionClick(index)}
key={index}
>
<Typography variant="body3" genericFontFamily="sans-serif">
{content}
{content.title}
</Typography>
</Section>
))}

View File

@ -30,15 +30,16 @@ export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
date: post.modifiedAt,
title: post.title,
summary: post.summary,
text: post.text,
author: 'Jinho',
tags: post.tags,
toc: [
'The dangers of totalitarian surveillance',
'Orwellian Future',
'Privacy-enhancing technology and its benefits',
'Ethical considerations of privacy-enhancing technology',
],
//@ts-ignore
blocks: post.blocks
?.map((block) => `${block.html}\n`)
.slice(2)
.join(''), // temporary solution for HTML/CSS work
author: 'Cameron Williamson',
authorEmail: 'leo@acid.info',
tags: ['Tools', 'Cyber Punk', 'Docs'],
//@ts-ignore
toc: JSON.parse(post?.toc),
...(post.blocks && post.blocks!.length > 0
? { coverImage: post.blocks![0] as UnbodyImageBlock }
: {}),

View File

@ -15,11 +15,15 @@ export const getArticlePostQuery = (args: UnbodyExploreArgs = defaultArgs) =>
tags
createdAt
modifiedAt
text
toc
blocks{
...on ImageBlock{
url
alt
}
... on TextBlock {
footnotes
html
}
}
`)