Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 143 additions & 101 deletions src/components/MomentDigest/Feed/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Link from 'next/link'
import React from 'react'
import { FormattedMessage } from 'react-intl'

import IconDot from '@/public/static/icons/dot.svg'
Expand Down Expand Up @@ -31,24 +32,26 @@ export type MomentDigestFeedProps = {
hasCommentedFollowees?: boolean
}

export const MomentDigestFeed = ({
type ContainerProps = {
moment: MomentDigestFeedProps['moment']
hasAuthor?: boolean
hasCommentedFollowees?: boolean
openMomentDetail: () => void
}

const Container = ({
moment,
hasAuthor,
hasCommentedFollowees,
}: MomentDigestFeedProps) => {
openMomentDetail,
}: ContainerProps) => {
const { content, createdAt, assets, author } = moment
const { router } = useRoute()

const momentDetailPath = toPath({
page: 'momentDetail',
moment,
})

const goToMomentDetail = () => {
setReferrer()
router.push(momentDetailPath.href)
}

const setReferrer = () => {
sessionStorage.set(MOMENT_DIGEST_REFERRER, true)
}
Expand All @@ -57,117 +60,156 @@ export const MomentDigestFeed = ({
setReferrer()
}

const Container = ({
openMomentDetail,
hasAuthor,
}: {
openMomentDetail: () => void
hasAuthor?: boolean
}) => {
return (
<section className={styles.container}>
<header className={styles.header}>
{hasAuthor && (
<section
className={styles.author}
data-test-id={TEST_ID.MOMENT_DIGEST_AUTHOR}
>
<UserDigest.Mini
user={author}
avatarSize={20}
textSize={12}
hasAvatar
hasDisplayName
/>
<Icon icon={IconDot} color="greyLight" size={20} />
</section>
)}
<section>
<Link {...momentDetailPath} onClick={handleClickDateTime}>
<DateTime date={createdAt} color="grey" minimal />
</Link>
</section>
</header>
{!!content && (
return (
<section className={styles.container}>
<header className={styles.header}>
{hasAuthor && (
<section
className={styles.content}
onClick={(event) => {
const target = event.target as HTMLElement
const targetTagName = target.tagName.toLowerCase()
if (
// link
targetTagName === 'a' ||
// mention
(targetTagName === 'span' &&
target.parentElement?.tagName.toLowerCase() === 'a' &&
target.innerText.includes('@'))
) {
event.stopPropagation()
return
}
openMomentDetail()
}}
data-test-id={TEST_ID.MOMENT_DIGEST_CONTENT}
className={styles.author}
data-test-id={TEST_ID.MOMENT_DIGEST_AUTHOR}
>
<Expandable
content={content}
limit={4}
isRichShow={true}
size={15}
collapseable={false}
isCommentOrMoment
expandButton={
<button
onClick={() => {
// TODO: open moment detail dialog or navigate to moment detail page
}}
>
<FormattedMessage
defaultMessage="More"
id="eoQN04"
description="src/components/MomentDigest/index.tsx"
/>
</button>
}
>
<section
className="u-content-moment"
dangerouslySetInnerHTML={{
__html: content || '',
}}
onClick={captureClicks}
/>
</Expandable>
<UserDigest.Mini
user={author}
avatarSize={20}
textSize={12}
hasAvatar
hasDisplayName
/>
<Icon icon={IconDot} color="greyLight" size={20} />
</section>
)}
{!!assets && assets.length > 0 && (
<section className={styles.assets}>
<Assets moment={moment} />
</section>
)}
<FooterActions
moment={moment}
hasCommentedFollowees={hasCommentedFollowees}
onClickReply={openMomentDetail}
/>
</section>
)
<section>
<Link {...momentDetailPath} onClick={handleClickDateTime}>
<DateTime date={createdAt} color="grey" minimal />
</Link>
</section>
</header>
{!!content && (
<section
className={styles.content}
onClick={(event) => {
const target = event.target as HTMLElement
const targetTagName = target.tagName.toLowerCase()
if (
// link
targetTagName === 'a' ||
// mention
(targetTagName === 'span' &&
target.parentElement?.tagName.toLowerCase() === 'a' &&
target.innerText.includes('@'))
) {
event.stopPropagation()
return
}
openMomentDetail()
}}
data-test-id={TEST_ID.MOMENT_DIGEST_CONTENT}
>
<Expandable
content={content}
limit={4}
isRichShow={true}
size={15}
collapseable={false}
isCommentOrMoment
expandButton={
<button
onClick={() => {
// TODO: open moment detail dialog or navigate to moment detail page
}}
>
<FormattedMessage
defaultMessage="More"
id="eoQN04"
description="src/components/MomentDigest/index.tsx"
/>
</button>
}
>
<section
className="u-content-moment"
dangerouslySetInnerHTML={{
__html: content || '',
}}
onClick={captureClicks}
/>
</Expandable>
</section>
)}
{!!assets && assets.length > 0 && (
<section className={styles.assets}>
<Assets moment={moment} />
</section>
)}
<FooterActions
moment={moment}
hasCommentedFollowees={hasCommentedFollowees}
onClickReply={openMomentDetail}
/>
</section>
)
}

const BaseMomentDigestFeed = ({
moment,
hasAuthor,
hasCommentedFollowees,
}: MomentDigestFeedProps) => {
const { router } = useRoute()

const momentDetailPath = toPath({
page: 'momentDetail',
moment,
})

const setReferrer = () => {
sessionStorage.set(MOMENT_DIGEST_REFERRER, true)
}

const goToMomentDetail = () => {
setReferrer()
router.push(momentDetailPath.href)
}

return (
<>
<Media lessThan="md">
<Container openMomentDetail={goToMomentDetail} hasAuthor={hasAuthor} />
<Container
moment={moment}
hasAuthor={hasAuthor}
hasCommentedFollowees={hasCommentedFollowees}
openMomentDetail={goToMomentDetail}
/>
</Media>
<Media greaterThanOrEqual="md">
<MomentDetailDialog shortHash={moment.shortHash}>
{({ openDialog }) => (
<Container openMomentDetail={openDialog} hasAuthor={hasAuthor} />
<Container
moment={moment}
hasAuthor={hasAuthor}
hasCommentedFollowees={hasCommentedFollowees}
openMomentDetail={openDialog}
/>
)}
</MomentDetailDialog>
</Media>
</>
)
}

type MemoizedMomentDigestFeed = React.MemoExoticComponent<
React.FC<MomentDigestFeedProps>
> & {
fragments: typeof fragments
}

export const MomentDigestFeed = React.memo(
BaseMomentDigestFeed,
({ moment: prev }, { moment: next }) =>
prev.liked === next.liked &&
prev.likeCount === next.likeCount &&
prev.commentCount === next.commentCount &&
prev.state === next.state
) as MemoizedMomentDigestFeed

MomentDigestFeed.fragments = fragments
2 changes: 2 additions & 0 deletions src/views/HottestMoments/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ const momentConnectionFragment = gql`
cursor
node {
...MomentDigestFeedMomentPublic
...MomentDigestFeedMomentPrivate
}
}
}
${MomentDigestFeed.fragments.moment.public}
${MomentDigestFeed.fragments.moment.private}
`

export const HOTTEST_MOMENTS_PUBLIC = gql`
Expand Down
Loading