Skip to content

Commit

Permalink
refactor: extract Infinite Scroll Logic into Reusable Component
Browse files Browse the repository at this point in the history
  • Loading branch information
Kechicode committed Nov 27, 2024
1 parent 7b0a5a3 commit a2829db
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 167 deletions.
64 changes: 64 additions & 0 deletions src/components/TagList/InfiniteTagList.tsx
Original file line number Diff line number Diff line change
@@ -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<any>
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 (
<InfiniteScroll
hasNextPage={pageInfo.hasNextPage && edges.length < maxResults}
loadMore={loadMore}
eof={
showEOFMessage && (
<FormattedMessage defaultMessage="End of the results" id="ui1+QC" />
)
}
>
<ul className={styles.tagList}>
{edges.map(({ node, cursor }, i) =>
node.__typename === 'Tag' ? (
<li key={cursor || node.id} className={styles.tagListItem}>
<TagDigest.Feed
tag={node}
onClick={() =>
analytics.trackEvent('click_feed', {
type: trackingType,
contentType: 'tag',
location: i,
id: node.id,
...(searchKey && { searchKey }),
})
}
/>
</li>
) : null
)}
</ul>
</InfiniteScroll>
)
}

export default InfiniteTagList
5 changes: 5 additions & 0 deletions src/components/TagList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Infinite from './InfiniteTagList'

export const TagList = {
Infinite,
}
54 changes: 54 additions & 0 deletions src/components/TagList/styles.module.css
Original file line number Diff line number Diff line change
@@ -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));
}
}
}
}
}
1 change: 1 addition & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
41 changes: 8 additions & 33 deletions src/views/Search/AggregateResults/Tags.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useEffect } from 'react'
import { FormattedMessage } from 'react-intl'

import {
LATER_SEARCH_RESULTS_LENGTH,
Expand All @@ -8,9 +7,8 @@ import {
import { analytics, mergeConnections } from '~/common/utils'
import {
EmptySearch,
InfiniteScroll,
SpinnerBlock,
TagDigest,
TagList,
Translate,
usePublicQuery,
useRoute,
Expand Down Expand Up @@ -94,37 +92,14 @@ const AggregateTagResults = () => {

return (
<section className={styles.aggregateSection}>
<InfiniteScroll
hasNextPage={
pageInfo.hasNextPage && edges.length < MAX_SEARCH_RESULTS_LENGTH
}
<TagList.Infinite
edges={edges}
pageInfo={pageInfo}
loadMore={loadMore}
eof={
<FormattedMessage defaultMessage="End of the results" id="ui1+QC" />
}
>
<ul className={styles.tagList}>
{edges.map(
({ node, cursor }, i) =>
node.__typename === 'Tag' && (
<li key={cursor} className={styles.tagListItem}>
<TagDigest.Feed
tag={node}
onClick={() =>
analytics.trackEvent('click_feed', {
type: 'search_tag',
contentType: 'tag',
location: i,
id: node.id,
searchKey: q,
})
}
/>
</li>
)
)}
</ul>
</InfiniteScroll>
trackingType="search_tag"
searchKey={q}
maxResults={MAX_SEARCH_RESULTS_LENGTH}
/>
</section>
)
}
Expand Down
55 changes: 0 additions & 55 deletions src/views/Search/AggregateResults/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 6 additions & 25 deletions src/views/Tags/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -65,29 +63,12 @@ const Feed = ({ type }: Props) => {

return (
<Layout.Main.Spacing hasVertical={false}>
<InfiniteScroll
hasNextPage={pageInfo.hasNextPage}
<TagList.Infinite
edges={edges}
pageInfo={pageInfo}
loadMore={loadMore}
eof
>
<ul className={styles.list}>
{edges.map(({ node: tag }, i) => (
<li key={tag.id} className={styles.listItem}>
<TagDigest.Feed
tag={tag}
onClick={() =>
analytics.trackEvent('click_feed', {
type: trackingType,
contentType: 'tag',
location: i,
id: tag.id,
})
}
/>
</li>
))}
</ul>
</InfiniteScroll>
trackingType={isRecommended ? 'all_tags_recommended' : 'all_tags'}
/>
</Layout.Main.Spacing>
)
}
Expand Down
54 changes: 0 additions & 54 deletions src/views/Tags/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
}
}

0 comments on commit a2829db

Please sign in to comment.