Skip to content

Commit

Permalink
fix: archived articles virtual scrolling (#1077)
Browse files Browse the repository at this point in the history
  • Loading branch information
bicstone authored Jun 22, 2024
1 parent 15939c5 commit 38610cf
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 26 deletions.
57 changes: 57 additions & 0 deletions src/features/Timeline/TimelineItemCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import styled, { type CSSObject } from "@emotion/styled";
import { type CardProps } from "@mui/material/Card";
import { alpha } from "@mui/material/styles";
import { graphql } from "gatsby";

import { TimelineCardBase } from "../Timeline/TimelineCardBase";

import { QiitaIcon } from "@/components/icons/QiitaIcon";
import { type TimelineItemCardFragment } from "@/generated/graphqlTypes";
import { type M3ColorTokens, outputColorTokens } from "@/layouts/themes";

export const query = graphql`
fragment TimelineItemCard on QiitaJson {
title
url
}
`;

const adoptColorTokens = (colorTokens: M3ColorTokens): CSSObject => {
const background = colorTokens.surfaceVariant;
const color = colorTokens.onSurface;

return {
background,
color,
"&:hover": {
background: alpha(background, 0.8),
},
};
};

const StyledTimelineCard = styled(TimelineCardBase)(({ theme }) => {
return {
...adoptColorTokens(outputColorTokens.lightColorTokens),
[theme.getColorSchemeSelector("dark")]: adoptColorTokens(
outputColorTokens.darkColorTokens,
),
};
});

export type TimelineItemCardProps = {
item: TimelineItemCardFragment;
} & CardProps;

export const TimelineItemCard = ({
item,
...props
}: TimelineItemCardProps): JSX.Element => {
return (
<StyledTimelineCard
avatar={<QiitaIcon aria-hidden="true" />}
title={item.title}
url={item.url}
{...props}
/>
);
};
39 changes: 26 additions & 13 deletions src/features/Timeline/TimelineVirtualizedList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import { type ComponentProps, forwardRef } from "react";
import { VirtuosoGrid } from "react-virtuoso";

import { TimelineArticleCard } from "./TimelineArticleCard";
import { TimelineItemCard } from "./TimelineItemCard";
import { TimelineMdxCard } from "./TimelineMdxCard";
import { TimelineNoteCard } from "./TimelineNoteCard";
import { TimelineSlideCard } from "./TimelineSlideCard";
import { CARD_HEIGHT } from "./constants";

import { type TimelineVirtualizedListTimelineFragment } from "@/generated/graphqlTypes";
import {
type TimelineVirtualizedListArchivedFragment,
type TimelineVirtualizedListTimelineFragment,
} from "@/generated/graphqlTypes";

export const query = graphql`
fragment TimelineVirtualizedListTimeline on TimelineConnection {
Expand All @@ -33,10 +37,21 @@ export const query = graphql`
}
}
}
fragment TimelineVirtualizedListArchived on QiitaJsonConnection {
nodes {
__typename
id
dateX: created_at
...TimelineItemCard
}
}
`;

interface TimelineItemProps {
item: TimelineVirtualizedListTimelineFragment["nodes"][number];
item:
| TimelineVirtualizedListTimelineFragment["nodes"][number]
| TimelineVirtualizedListArchivedFragment["nodes"][number];
}

const TimelineItem = ({ item }: TimelineItemProps): JSX.Element | null => {
Expand All @@ -57,6 +72,10 @@ const TimelineItem = ({ item }: TimelineItemProps): JSX.Element | null => {
return <TimelineMdxCard key={item.id} item={item} showYear />;
}

case "QiitaJson": {
return <TimelineItemCard key={item.id} item={item} />;
}

default: {
return null;
}
Expand All @@ -81,7 +100,9 @@ const Container = forwardRef<
Container.displayName = "Container";

export interface TimelineVirtualizedListProps {
items: TimelineVirtualizedListTimelineFragment;
items:
| TimelineVirtualizedListTimelineFragment
| TimelineVirtualizedListArchivedFragment;
}

export const TimelineVirtualizedList = ({
Expand All @@ -90,13 +111,6 @@ export const TimelineVirtualizedList = ({
const minHeightSingleColumn = (CARD_HEIGHT + 24) * (items.nodes.length + 1);
const minHeightDoubleColumn = minHeightSingleColumn / 2;

// XXX: Gatsby でなぜかソートされないことがあるため
// クライアント側でもう一回ソートする
// 重くなるため早めに原因特定したい
const sortedItems = Array.from(items.nodes).sort((a, b) => {
return Number(b.dateX) - Number(a.dateX);
});

const FallBack = (): JSX.Element => (
<div
aria-busy="true"
Expand All @@ -115,10 +129,9 @@ export const TimelineVirtualizedList = ({
return (
<NoSsr defer fallback={<FallBack />}>
<VirtuosoGrid
data={sortedItems}
data={[...items.nodes]}
components={{
// XXX: override type definition
List: Container as React.FunctionComponent,
List: Container,
}}
itemContent={(index, item) => <TimelineItem key={index} item={item} />}
css={(theme) => ({
Expand Down
16 changes: 13 additions & 3 deletions src/generated/graphqlTypes.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/layouts/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export const Footer = (): JSX.Element => {
<Link component={RouterLink} color="inherit" to="/">
ホーム
</Link>
<Link component={RouterLink} color="inherit" to="/outputs">
アウトプット
</Link>
<Link
color="inherit"
href={SITE_METADATA.profileLink}
Expand Down
7 changes: 3 additions & 4 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { Spacer } from "@/components/Spacer";
import { SITE_METADATA } from "@/constants/SITE_METADATA";
import { BioCardList } from "@/features/Bio";
import { TimelineVirtualizedList } from "@/features/Timeline";
import { ArchivedList } from "@/features/TimelineArchived";
import { FeaturedList } from "@/features/TimelineFeatured";
import { HeadTemplate } from "@/layouts/HeadTemplate";

Expand All @@ -18,8 +17,8 @@ export const query = graphql`
timelineItems: allTimeline(sort: { date: DESC }) {
...TimelineVirtualizedListTimeline
}
qiitaItems: allQiitaJson(sort: { created_at: DESC }) {
...TimelineArchivedList
qiitaItems: allQiitaJson(sort: { title: ASC }) {
...TimelineVirtualizedListArchived
}
}
`;
Expand Down Expand Up @@ -68,7 +67,7 @@ const IndexPage = ({ data }: PageProps<IndexPageQuery>): JSX.Element => {
Archived
</Typography>
<Spacer y={6} />
<ArchivedList items={qiitaItems} />
<TimelineVirtualizedList items={qiitaItems} />
<Spacer y={6} />
</Container>
</>
Expand Down
15 changes: 9 additions & 6 deletions src/pages/outputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const query = graphql`
outputs: allOutput(sort: { date: DESC }) {
...TimelineListOutput
}
qiitaItems: allQiitaJson(sort: { created_at: DESC }) {
qiitaItems: allQiitaJson(sort: { title: ASC }) {
...TimelineArchivedList
}
site {
Expand Down Expand Up @@ -96,17 +96,20 @@ const OutputsPage = ({ data }: PageProps<OutputsPageQuery>): JSX.Element => {
css={(theme) => ({ margin: theme.spacing(4, "auto") })}
>
<Breadcrumbs title={title} />
<Spacer y={4} />
<Spacer y={6} />
<Typography variant="h5" component="h2" fontWeight="bold">
Outputs
</Typography>
<TimelineList groups={outputGroups} />
<Spacer y={4} />
<Breadcrumbs title={title} />
<Spacer y={2} />
<Spacer y={6} />
<Typography variant="h5" component="h2" fontWeight="bold">
Archived
</Typography>
<Spacer y={6} />
<Spacer y={4} />
<ArchivedList items={qiitaItems} />
<Spacer y={6} />
<Breadcrumbs title={title} />
<Spacer y={6} />
</Container>
);
};
Expand Down

0 comments on commit 38610cf

Please sign in to comment.