From a2829dbfebc4ac1e054c4aa1165089ffe69d9b57 Mon Sep 17 00:00:00 2001 From: Kechicode <186776112+Kechicode@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:34:40 +0800 Subject: [PATCH] refactor: extract Infinite Scroll Logic into Reusable Component --- src/components/TagList/InfiniteTagList.tsx | 64 +++++++++++++++++++ src/components/TagList/index.tsx | 5 ++ src/components/TagList/styles.module.css | 54 ++++++++++++++++ src/components/index.tsx | 1 + src/views/Search/AggregateResults/Tags.tsx | 41 +++--------- .../Search/AggregateResults/styles.module.css | 55 ---------------- src/views/Tags/Feed.tsx | 31 ++------- src/views/Tags/styles.module.css | 54 ---------------- 8 files changed, 138 insertions(+), 167 deletions(-) create mode 100644 src/components/TagList/InfiniteTagList.tsx create mode 100644 src/components/TagList/index.tsx create mode 100644 src/components/TagList/styles.module.css diff --git a/src/components/TagList/InfiniteTagList.tsx b/src/components/TagList/InfiniteTagList.tsx new file mode 100644 index 0000000000..5e0ea8c9ac --- /dev/null +++ b/src/components/TagList/InfiniteTagList.tsx @@ -0,0 +1,64 @@ +import { FormattedMessage } from 'react-intl' + +import { analytics } from '~/common/utils' +import { InfiniteScroll, TagDigest } from '~/components' + +import styles from './styles.module.css' + +interface Props { + edges: Array<{ node: any; cursor?: string }> + pageInfo: { + hasNextPage: boolean + endCursor?: string | null + } + loadMore: () => Promise + trackingType: 'search_tag' | 'all_tags' | 'all_tags_recommended' + searchKey?: string + maxResults?: number + showEOFMessage?: boolean +} + +const InfiniteTagList = ({ + edges, + pageInfo, + loadMore, + trackingType, + searchKey, + maxResults = Infinity, + showEOFMessage = true, +}: Props) => { + return ( + + ) + } + > + + + ) +} + +export default InfiniteTagList diff --git a/src/components/TagList/index.tsx b/src/components/TagList/index.tsx new file mode 100644 index 0000000000..e05e63110c --- /dev/null +++ b/src/components/TagList/index.tsx @@ -0,0 +1,5 @@ +import Infinite from './InfiniteTagList' + +export const TagList = { + Infinite, +} diff --git a/src/components/TagList/styles.module.css b/src/components/TagList/styles.module.css new file mode 100644 index 0000000000..bbc44fed00 --- /dev/null +++ b/src/components/TagList/styles.module.css @@ -0,0 +1,54 @@ +.tagList { + display: flex; + flex-wrap: wrap; + margin-top: var(--sp32); + + & .tagListItem { + @mixin border-bottom-grey-light; + + position: relative; + flex: 0 0 50%; + padding-bottom: var(--sp20); + margin-bottom: var(--sp20); + border-style: dashed; + + &:last-child { + flex-grow: 1; + } + } + + @media (--sm-down) { + & .tagListItem { + &:nth-child(2n + 1) { + padding-right: var(--sp16); + } + + &:last-child { + padding-right: 0; + + & a { + max-width: calc(50% - var(--sp16)); + } + } + } + } + + @media (--sm-up) { + & .tagListItem { + flex: 0 0 33.3333%; + + &:nth-child(3n + 1), + &:nth-child(3n + 2) { + padding-right: var(--sp16); + } + + &:last-child { + padding-right: 0; + + & a { + max-width: calc(33.3333% - var(--sp16)); + } + } + } + } +} diff --git a/src/components/index.tsx b/src/components/index.tsx index 5dfc6f01f4..6a28e147f3 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -74,6 +74,7 @@ export * from './Protected' export * from './ReCaptcha' export * from './Search' export * from './TagDigest' +export * from './TagList' export * from './TextSelectionPopover' export * from './Throw404' export * from './Transaction' diff --git a/src/views/Search/AggregateResults/Tags.tsx b/src/views/Search/AggregateResults/Tags.tsx index 07df228540..fe35990fa5 100644 --- a/src/views/Search/AggregateResults/Tags.tsx +++ b/src/views/Search/AggregateResults/Tags.tsx @@ -1,5 +1,4 @@ import { useEffect } from 'react' -import { FormattedMessage } from 'react-intl' import { LATER_SEARCH_RESULTS_LENGTH, @@ -8,9 +7,8 @@ import { import { analytics, mergeConnections } from '~/common/utils' import { EmptySearch, - InfiniteScroll, SpinnerBlock, - TagDigest, + TagList, Translate, usePublicQuery, useRoute, @@ -94,37 +92,14 @@ const AggregateTagResults = () => { return (
- - } - > -
    - {edges.map( - ({ node, cursor }, i) => - node.__typename === 'Tag' && ( -
  • - - analytics.trackEvent('click_feed', { - type: 'search_tag', - contentType: 'tag', - location: i, - id: node.id, - searchKey: q, - }) - } - /> -
  • - ) - )} -
-
+ trackingType="search_tag" + searchKey={q} + maxResults={MAX_SEARCH_RESULTS_LENGTH} + />
) } diff --git a/src/views/Search/AggregateResults/styles.module.css b/src/views/Search/AggregateResults/styles.module.css index bc4162c781..b664c825a3 100644 --- a/src/views/Search/AggregateResults/styles.module.css +++ b/src/views/Search/AggregateResults/styles.module.css @@ -32,61 +32,6 @@ padding: var(--sp16); } -.tagList { - display: flex; - flex-wrap: wrap; - margin-top: var(--sp32); - - & .tagListItem { - @mixin border-bottom-grey-light; - - position: relative; - flex: 0 0 50%; - padding-bottom: var(--sp20); - margin-bottom: var(--sp20); - border-style: dashed; - - &:last-child { - flex-grow: 1; - } - } - - @media (--sm-down) { - & .tagListItem { - &:nth-child(2n + 1) { - padding-right: var(--sp16); - } - - &:last-child { - padding-right: 0; - - & a { - max-width: calc(50% - var(--sp16)); - } - } - } - } - - @media (--sm-up) { - & .tagListItem { - flex: 0 0 33.3333%; - - &:nth-child(3n + 1), - &:nth-child(3n + 2) { - padding-right: var(--sp16); - } - - &:last-child { - padding-right: 0; - - & a { - max-width: calc(33.3333% - var(--sp16)); - } - } - } - } -} - .tabs { padding: 0 var(--sp16); margin: var(--sp32) 0 var(--sp16); diff --git a/src/views/Tags/Feed.tsx b/src/views/Tags/Feed.tsx index 40f6b55f50..7d286e01b2 100644 --- a/src/views/Tags/Feed.tsx +++ b/src/views/Tags/Feed.tsx @@ -3,17 +3,15 @@ import _get from 'lodash/get' import { analytics, mergeConnections } from '~/common/utils' import { EmptyTag, - InfiniteScroll, Layout, QueryError, SpinnerBlock, - TagDigest, + TagList, usePublicQuery, } from '~/components' import { AllTagsHottestQuery } from '~/gql/graphql' import { ALL_TAGS_HOTTEST } from './gql' -import styles from './styles.module.css' export type FeedType = 'recommended' | 'hottest' @@ -65,29 +63,12 @@ const Feed = ({ type }: Props) => { return ( - -
    - {edges.map(({ node: tag }, i) => ( -
  • - - analytics.trackEvent('click_feed', { - type: trackingType, - contentType: 'tag', - location: i, - id: tag.id, - }) - } - /> -
  • - ))} -
-
+ trackingType={isRecommended ? 'all_tags_recommended' : 'all_tags'} + />
) } diff --git a/src/views/Tags/styles.module.css b/src/views/Tags/styles.module.css index 0c882e9a39..b40985fb44 100644 --- a/src/views/Tags/styles.module.css +++ b/src/views/Tags/styles.module.css @@ -5,57 +5,3 @@ margin-top: var(--sp32); } } - -.list { - display: flex; - flex-wrap: wrap; - - & .listItem { - @mixin border-bottom-grey-light; - - position: relative; - flex: 0 0 50%; - padding-bottom: var(--sp20); - margin-bottom: var(--sp20); - border-style: dashed; - - &:last-child { - flex-grow: 1; - } - } - - @media (--sm-down) { - & .listItem { - &:nth-child(2n + 1) { - padding-right: var(--sp16); - } - - &:last-child { - padding-right: 0; - - & a { - max-width: calc(50% - var(--sp16)); - } - } - } - } - - @media (--sm-up) { - & .listItem { - flex: 0 0 33.3333%; - - &:nth-child(3n + 1), - &:nth-child(3n + 2) { - padding-right: var(--sp16); - } - - &:last-child { - padding-right: 0; - - & a { - max-width: calc(33.3333% - var(--sp16)); - } - } - } - } -}