diff --git a/content b/content
index 301acded..02a9411f 160000
--- a/content
+++ b/content
@@ -1 +1 @@
-Subproject commit 301acded2e4b87ee1d4cf5edba3587b33feabbbd
+Subproject commit 02a9411f97dd5a1c6515abcc6275260a008abef9
diff --git a/content-sample/featured/featured.yml b/content-sample/featured/featured.yml
new file mode 100644
index 00000000..958a1826
--- /dev/null
+++ b/content-sample/featured/featured.yml
@@ -0,0 +1,15 @@
+- title: コードレビューにラベルを付けるだけでチームの心理的安全性を高めた話
+ ogImage: https://res.cloudinary.com/zenn/image/upload/s--v4nig1Q6--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E3%2582%25B3%25E3%2583%25BC%25E3%2583%2589%25E3%2583%25AC%25E3%2583%2593%25E3%2583%25A5%25E3%2583%25BC%25E3%2581%25AB%25E3%2583%25A9%25E3%2583%2599%25E3%2583%25AB%25E3%2582%2592%25E4%25BB%2598%25E3%2581%2591%25E3%2582%258B%25E3%2581%25A0%25E3%2581%2591%25E3%2581%25A7%25E3%2583%2581%25E3%2583%25BC%25E3%2583%25A0%25E3%2581%25AE%25E5%25BF%2583%25E7%2590%2586%25E7%259A%2584%25E5%25AE%2589%25E5%2585%25A8%25E6%2580%25A7%25E3%2582%2592%25E9%25AB%2598%25E3%2582%2581%25E3%2581%259F%25E8%25A9%25B1%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_34:%25E3%2581%258A%25E3%2581%258A%25E3%2581%2584%25E3%2581%2597%2520%2528bicstone%2529%2Cx_220%2Cy_108/bo_3px_solid_rgb:d6e3ed%2Cg_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzEzYjhhODE4MTUuanBlZw==%2Cr_20%2Cw_90%2Cx_92%2Cy_102/g_south_west%2Ch_34%2Cl_default:og-publication-pro-mark-xcosax%2Cw_34%2Cx_217%2Cy_158/co_rgb:6e7b85%2Cg_south_west%2Cl_text:notosansjp-medium.otf_30:Hacobell%2520Developers%2520...%2Cx_255%2Cy_160/bo_4px_solid_white%2Cg_south_west%2Ch_50%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2JiNDU0ZDlmNDIuanBlZw==%2Cr_max%2Cw_50%2Cx_139%2Cy_84/v1627283836/default/og-base-w1200-v2.png
+ url: https://zenn.dev/hacobell_dev/articles/code-review-comment-prefix
+
+- title: もうブロッカーにしない!コードレビューを爆速にするための組織づくり
+ ogImage: https://res.cloudinary.com/zenn/image/upload/s--aKD8gWBw--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E3%2582%2582%25E3%2581%2586%25E3%2583%2596%25E3%2583%25AD%25E3%2583%2583%25E3%2582%25AB%25E3%2583%25BC%25E3%2581%25AB%25E3%2581%2597%25E3%2581%25AA%25E3%2581%2584%25EF%25BC%2581%25E3%2582%25B3%25E3%2583%25BC%25E3%2583%2589%25E3%2583%25AC%25E3%2583%2593%25E3%2583%25A5%25E3%2583%25BC%25E3%2582%2592%25E7%2588%2586%25E9%2580%259F%25E3%2581%25AB%25E3%2581%2599%25E3%2582%258B%25E3%2581%259F%25E3%2582%2581%25E3%2581%25AE%25E7%25B5%2584%25E7%25B9%2594%25E3%2581%25A5%25E3%2581%258F%25E3%2582%258A%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_34:%25E3%2581%258A%25E3%2581%258A%25E3%2581%2584%25E3%2581%2597%2520%2528bicstone%2529%2Cx_220%2Cy_108/bo_3px_solid_rgb:d6e3ed%2Cg_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzEzYjhhODE4MTUuanBlZw==%2Cr_20%2Cw_90%2Cx_92%2Cy_102/g_south_west%2Ch_34%2Cl_default:og-publication-pro-mark-xcosax%2Cw_34%2Cx_217%2Cy_158/co_rgb:6e7b85%2Cg_south_west%2Cl_text:notosansjp-medium.otf_30:Hacobell%2520Developers%2520...%2Cx_255%2Cy_160/bo_4px_solid_white%2Cg_south_west%2Ch_50%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2JiNDU0ZDlmNDIuanBlZw==%2Cr_max%2Cw_50%2Cx_139%2Cy_84/v1627283836/default/og-base-w1200-v2.png
+ url: https://zenn.dev/hacobell_dev/articles/code-review-blocker
+
+- title: 【GraphQL】スキーマ駆動開発におけるエラーレスポンス設計パターン集
+ ogImage: https://res.cloudinary.com/zenn/image/upload/s--siLULLTQ--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E3%2580%2590GraphQL%25E3%2580%2591%25E3%2582%25B9%25E3%2582%25AD%25E3%2583%25BC%25E3%2583%259E%25E9%25A7%2586%25E5%258B%2595%25E9%2596%258B%25E7%2599%25BA%25E3%2581%25AB%25E3%2581%258A%25E3%2581%2591%25E3%2582%258B%25E3%2582%25A8%25E3%2583%25A9%25E3%2583%25BC%25E3%2583%25AC%25E3%2582%25B9%25E3%2583%259D%25E3%2583%25B3%25E3%2582%25B9%25E8%25A8%25AD%25E8%25A8%2588%25E3%2583%2591%25E3%2582%25BF%25E3%2583%25BC%25E3%2583%25B3%25E9%259B%2586%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_34:%25E3%2581%258A%25E3%2581%258A%25E3%2581%2584%25E3%2581%2597%2520%2528bicstone%2529%2Cx_220%2Cy_108/bo_3px_solid_rgb:d6e3ed%2Cg_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzEzYjhhODE4MTUuanBlZw==%2Cr_20%2Cw_90%2Cx_92%2Cy_102/g_south_west%2Ch_34%2Cl_default:og-publication-pro-mark-xcosax%2Cw_34%2Cx_217%2Cy_158/co_rgb:6e7b85%2Cg_south_west%2Cl_text:notosansjp-medium.otf_30:Hacobell%2520Developers%2520...%2Cx_255%2Cy_160/bo_4px_solid_white%2Cg_south_west%2Ch_50%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2JiNDU0ZDlmNDIuanBlZw==%2Cr_max%2Cw_50%2Cx_139%2Cy_84/v1627283836/default/og-base-w1200-v2.png
+ url: https://zenn.dev/hacobell_dev/articles/graphql-error-response
+
+- title: アウトプットはどうして続かないのか?「モチベの泉」を枯らさない5つの掟
+ ogImage: https://res.cloudinary.com/zenn/image/upload/s--xyXWCiYY--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E3%2582%25A2%25E3%2582%25A6%25E3%2583%2588%25E3%2583%2597%25E3%2583%2583%25E3%2583%2588%25E3%2581%25AF%25E3%2581%25A9%25E3%2581%2586%25E3%2581%2597%25E3%2581%25A6%25E7%25B6%259A%25E3%2581%258B%25E3%2581%25AA%25E3%2581%2584%25E3%2581%25AE%25E3%2581%258B%25EF%25BC%259F%25E3%2580%258C%25E3%2583%25A2%25E3%2583%2581%25E3%2583%2599%25E3%2581%25AE%25E6%25B3%2589%25E3%2580%258D%25E3%2582%2592%25E6%259E%25AF%25E3%2582%2589%25E3%2581%2595%25E3%2581%25AA%25E3%2581%25845%25E3%2581%25A4%25E3%2581%25AE%25E6%258E%259F%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:%25E3%2581%258A%25E3%2581%258A%25E3%2581%2584%25E3%2581%2597%2520%2528bicstone%2529%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2JiNDU0ZDlmNDIuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png
+ url: https://zenn.dev/bicstone/articles/keep-you-motivated-to-output
diff --git a/gatsby-config.ts b/gatsby-config.ts
index 79e01032..56310d74 100644
--- a/gatsby-config.ts
+++ b/gatsby-config.ts
@@ -32,6 +32,7 @@ const contentPaths = [
"speakerdeck",
"zenn",
"note",
+ "featured",
];
const config: GatsbyConfig = {
diff --git a/src/features/Bio/BioCardList.tsx b/src/features/Bio/BioCardList.tsx
index 8494b13d..540f7e2f 100644
--- a/src/features/Bio/BioCardList.tsx
+++ b/src/features/Bio/BioCardList.tsx
@@ -8,8 +8,6 @@ import { FacebookIcon } from "@/components/icons/FacebookIcon";
import { GitHubIcon } from "@/components/icons/GitHubIcon";
import { LinkedInIcon } from "@/components/icons/LinkedInIcon";
import { NoteIcon } from "@/components/icons/NoteIcon";
-import { SpeakerDeckIcon } from "@/components/icons/SpeakerDeckIcon";
-import { ThreadsIcon } from "@/components/icons/ThreadsIcon";
import { XIcon } from "@/components/icons/XIcon";
import { YoutrustIcon } from "@/components/icons/YoutrustIcon";
import { ZennIcon } from "@/components/icons/ZennIcon";
@@ -17,15 +15,13 @@ import { ZennIcon } from "@/components/icons/ZennIcon";
export const BioCardList = (): JSX.Element => {
const linkKeys = [
"x",
+ "bluesky",
"facebook",
"linkedin",
- "bluesky",
- "threads",
"youtrust",
+ "github",
"zenn",
"note",
- "speakerdeck",
- "github",
] as const satisfies LinkKeys[];
const avatarMap = {
@@ -34,8 +30,6 @@ export const BioCardList = (): JSX.Element => {
github: ,
linkedin: ,
note: ,
- speakerdeck: ,
- threads: ,
x: ,
youtrust: ,
zenn: ,
diff --git a/src/features/Timeline/TimelinePinnedList.tsx b/src/features/Timeline/TimelinePinnedList.tsx
deleted file mode 100644
index 7f2a485f..00000000
--- a/src/features/Timeline/TimelinePinnedList.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import { TimelineItem } from "./TimelineList";
-
-// TODO: ベタ書きはやめたい
-const timelineItems = [
- {
- __typename: "NotesYaml",
- id: "0a72183c-ee23-5d74-8cad-73117d1fe3be",
- dateX: "1704787407",
- title: "バスの座席数がどんどん減っていく理由",
- date: "2024-01-09T08:03:27.000Z",
- url: "https://note.com/bicstone/n/n20ac6eae2e69",
- },
- {
- __typename: "ArticlesYaml",
- id: "13a1af26-aedc-5d4d-b658-bf792cb460cf",
- dateX: "1704758400",
- title:
- "アウトプットはどうして続かないのか?「モチベの泉」を枯らさない5つの掟",
- date: "2024-01-09T00:00:00.000Z",
- url: "https://zenn.dev/bicstone/articles/keep-you-motivated-to-output",
- },
- {
- __typename: "SlidesYaml",
- id: "787cee61-832c-5275-ad98-796d5fdfb085",
- dateX: "1702911600",
- title: "アウトプットのモチベーションを維持する4つの掟",
- date: "2023-12-18T15:00:00.000Z",
- url: "https://speakerdeck.com/bicstone/keep-you-motivated-to-output",
- },
- {
- __typename: "OssesYaml",
- id: "322e537a-3034-554e-b733-3b89cc131a89",
- dateX: "1701183600",
- title: "bicstone (npx card)",
- date: "2023-11-28T15:00:00.000Z",
- url: "https://github.com/bicstone/bicstone",
- },
- {
- __typename: "ArticlesYaml",
- id: "2ee07210-b6c7-57dd-96fb-9c8f69b7cc9f",
- dateX: "1695087000",
- title:
- "【GraphQL】スキーマ駆動開発におけるバリデーションの取り決め設計パターン集",
- date: "2023-09-19T01:30:00.000Z",
- url: "https://zenn.dev/bicstone/articles/graphql-validation",
- },
- {
- __typename: "ArticlesYaml",
- id: "f121165b-f87f-5582-b7c2-2748b4ad0de3",
- dateX: "1694398260",
- title: "【GraphQL】スキーマ駆動開発におけるエラーレスポンス設計パターン集",
- date: "2023-09-11T02:11:00.000Z",
- url: "https://zenn.dev/bicstone/articles/graphql-error-response",
- },
- {
- __typename: "SlidesYaml",
- id: "3e258fae-55ac-523e-8ead-084205654aee",
- dateX: "1688396400",
- title: "脱KPTで楽しく有意義に振り返り! Sailboat Retrospective",
- date: "2023-07-03T15:00:00.000Z",
- url: "https://speakerdeck.com/bicstone/kpt-to-sailboat-retrospective",
- },
- {
- __typename: "SlidesYaml",
- id: "f8dfb7a9-6cd3-58cb-aa09-9f7748c41161",
- dateX: "1686236400",
- title: "OSSのメンテナーになってみた / Becoming an OSS maintainer",
- date: "2023-06-08T15:00:00.000Z",
- url: "https://speakerdeck.com/bicstone/becoming-an-oss-maintainer",
- },
- {
- __typename: "ArticlesYaml",
- id: "bc7cdf9c-1304-50a4-8334-045181e01fc9",
- dateX: "1685926800",
- title: "GraphQL の配列が nullable になって扱いにくい問題の対処法",
- date: "2023-06-05T01:00:00.000Z",
- url: "https://zenn.dev/bicstone/articles/graphql-nullable",
- },
- {
- __typename: "SlidesYaml",
- id: "8e7460bf-bee1-57ac-bd7b-a37f6ec450fb",
- dateX: "1685286000",
- title:
- "ファイブフィンガーでスクラムチームの心理的安全性を高める / Fist to Five",
- date: "2023-05-28T15:00:00.000Z",
- url: "https://speakerdeck.com/bicstone/fist-to-five",
- },
- {
- __typename: "ArticlesYaml",
- id: "7c348ca6-33b7-53bb-b9fe-642bc21583b7",
- dateX: "1682904600",
- title: "月 1 回出社のハイブリッドワークでチームの信頼関係を育んだ話",
- date: "2023-05-01T01:30:00.000Z",
- url: "https://zenn.dev/bicstone/articles/hybrid-work-event",
- },
- {
- __typename: "ArticlesYaml",
- id: "a4c82202-ba98-5c3f-b5d4-c1a8ed08d7e4",
- dateX: "1680485400",
- title: "もうブロッカーにしない!コードレビューを爆速にするための組織づくり",
- date: "2023-04-03T01:30:00.000Z",
- url: "https://zenn.dev/bicstone/articles/code-review-blocker",
- },
- {
- __typename: "ArticlesYaml",
- id: "a015f8ab-6036-5217-9057-c5bdcf9aaf3f",
- dateX: "1678068000",
- title: "コードレビューにラベルを付けるだけでチームの心理的安全性を高めた話",
- date: "2023-03-06T02:00:00.000Z",
- url: "https://zenn.dev/bicstone/articles/code-review-comment-prefix",
- },
- {
- __typename: "OssesYaml",
- id: "06740451-e7e1-5315-84cc-3d4c51a792dc",
- dateX: "1573916400",
- title: "ra-language-japanese",
- date: "2019-11-16T15:00:00.000Z",
- url: "https://github.com/bicstone/ra-language-japanese",
- },
- {
- __typename: "OssesYaml",
- id: "1432a786-ba81-5c97-951c-f6046b44bf6b",
- dateX: "1573743600",
- title: "backlog-notify",
- date: "2019-11-14T15:00:00.000Z",
- url: "https://github.com/bicstone/backlog-notify",
- },
-] as const;
-
-export const TimelinePinnedList = (): JSX.Element => {
- return (
- <>
- {timelineItems.map((item) => (
-
- ))}
- >
- );
-};
diff --git a/src/features/Timeline/index.ts b/src/features/Timeline/index.ts
index 72cf7783..4e5c3d80 100644
--- a/src/features/Timeline/index.ts
+++ b/src/features/Timeline/index.ts
@@ -3,4 +3,3 @@ export {
TimelineVirtualizedList,
type TimelineVirtualizedListProps,
} from "./TimelineVirtualizedList";
-export { TimelinePinnedList } from "./TimelinePinnedList";
diff --git a/src/features/TimelineFeatured/FeaturedCard.tsx b/src/features/TimelineFeatured/FeaturedCard.tsx
new file mode 100644
index 00000000..a026f357
--- /dev/null
+++ b/src/features/TimelineFeatured/FeaturedCard.tsx
@@ -0,0 +1,62 @@
+import styled from "@emotion/styled";
+import Card from "@mui/material/Card";
+import CardActionArea from "@mui/material/CardActionArea";
+import { graphql } from "gatsby";
+
+import { type FeaturedCardFragment } from "@/generated/graphqlTypes";
+
+export const query = graphql`
+ fragment FeaturedCard on FeaturedYaml {
+ title
+ ogImage
+ url
+ }
+`;
+
+const StyledCard = styled(Card)({
+ width: "100%",
+ height: 0,
+ paddingBottom: "52.5%" /* 1200:630 Aspect Ratio */,
+ position: "relative",
+});
+
+const StyledCardActionArea = styled(CardActionArea)({
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: "100%",
+ height: "100%",
+}) as typeof CardActionArea;
+
+const StyledImage = styled("img")({
+ height: "100%",
+ width: "100%",
+});
+
+export const FeaturedCard = ({
+ item,
+}: {
+ item: FeaturedCardFragment;
+}): JSX.Element => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/src/features/TimelineFeatured/FeaturedList.tsx b/src/features/TimelineFeatured/FeaturedList.tsx
new file mode 100644
index 00000000..80a44e5a
--- /dev/null
+++ b/src/features/TimelineFeatured/FeaturedList.tsx
@@ -0,0 +1,40 @@
+import styled from "@emotion/styled";
+import { graphql } from "gatsby";
+
+import { FeaturedCard } from "./FeaturedCard";
+
+import { type FeaturedListFragment } from "@/generated/graphqlTypes";
+
+export const query = graphql`
+ fragment FeaturedList on FeaturedYamlConnection {
+ nodes {
+ __typename
+ id
+ ...FeaturedCard
+ }
+ }
+`;
+
+const Container = styled("div")(({ theme }) => ({
+ display: "grid",
+ gap: theme.spacing(3),
+ gridTemplateColumns: "repeat(2, 1fr)",
+ width: "100%",
+ [theme.breakpoints.down("md")]: {
+ gridTemplateColumns: "repeat(1, 1fr)",
+ },
+}));
+
+export const FeaturedList = ({
+ items,
+}: {
+ items: FeaturedListFragment;
+}): JSX.Element => {
+ return (
+
+ {items.nodes.map((item) => (
+
+ ))}
+
+ );
+};
diff --git a/src/features/TimelineFeatured/index.ts b/src/features/TimelineFeatured/index.ts
new file mode 100644
index 00000000..8c4318de
--- /dev/null
+++ b/src/features/TimelineFeatured/index.ts
@@ -0,0 +1 @@
+export { FeaturedList } from "./FeaturedList";
diff --git a/src/generated/graphqlTypes.ts b/src/generated/graphqlTypes.ts
index 298c506a..303091e1 100644
--- a/src/generated/graphqlTypes.ts
+++ b/src/generated/graphqlTypes.ts
@@ -626,6 +626,136 @@ export type DirectorySortInput = {
readonly uid: InputMaybe;
};
+export type FeaturedYaml = Node & {
+ readonly children: ReadonlyArray;
+ readonly id: Scalars['ID']['output'];
+ readonly internal: Internal;
+ readonly ogImage: Maybe;
+ readonly parent: Maybe;
+ readonly title: Maybe;
+ readonly url: Maybe;
+};
+
+export type FeaturedYamlConnection = {
+ readonly distinct: ReadonlyArray;
+ readonly edges: ReadonlyArray;
+ readonly group: ReadonlyArray;
+ readonly max: Maybe;
+ readonly min: Maybe;
+ readonly nodes: ReadonlyArray;
+ readonly pageInfo: PageInfo;
+ readonly sum: Maybe;
+ readonly totalCount: Scalars['Int']['output'];
+};
+
+
+export type FeaturedYamlConnectionDistinctArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlConnectionGroupArgs = {
+ field: FeaturedYamlFieldSelector;
+ limit: InputMaybe;
+ skip: InputMaybe;
+};
+
+
+export type FeaturedYamlConnectionMaxArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlConnectionMinArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlConnectionSumArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+export type FeaturedYamlEdge = {
+ readonly next: Maybe;
+ readonly node: FeaturedYaml;
+ readonly previous: Maybe;
+};
+
+export type FeaturedYamlFieldSelector = {
+ readonly children: InputMaybe;
+ readonly id: InputMaybe;
+ readonly internal: InputMaybe;
+ readonly ogImage: InputMaybe;
+ readonly parent: InputMaybe;
+ readonly title: InputMaybe;
+ readonly url: InputMaybe;
+};
+
+export type FeaturedYamlFilterInput = {
+ readonly children: InputMaybe;
+ readonly id: InputMaybe;
+ readonly internal: InputMaybe;
+ readonly ogImage: InputMaybe;
+ readonly parent: InputMaybe;
+ readonly title: InputMaybe;
+ readonly url: InputMaybe;
+};
+
+export type FeaturedYamlFilterListInput = {
+ readonly elemMatch: InputMaybe;
+};
+
+export type FeaturedYamlGroupConnection = {
+ readonly distinct: ReadonlyArray;
+ readonly edges: ReadonlyArray;
+ readonly field: Scalars['String']['output'];
+ readonly fieldValue: Maybe;
+ readonly group: ReadonlyArray;
+ readonly max: Maybe;
+ readonly min: Maybe;
+ readonly nodes: ReadonlyArray;
+ readonly pageInfo: PageInfo;
+ readonly sum: Maybe;
+ readonly totalCount: Scalars['Int']['output'];
+};
+
+
+export type FeaturedYamlGroupConnectionDistinctArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlGroupConnectionGroupArgs = {
+ field: FeaturedYamlFieldSelector;
+ limit: InputMaybe;
+ skip: InputMaybe;
+};
+
+
+export type FeaturedYamlGroupConnectionMaxArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlGroupConnectionMinArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+
+export type FeaturedYamlGroupConnectionSumArgs = {
+ field: FeaturedYamlFieldSelector;
+};
+
+export type FeaturedYamlSortInput = {
+ readonly children: InputMaybe;
+ readonly id: InputMaybe;
+ readonly internal: InputMaybe;
+ readonly ogImage: InputMaybe;
+ readonly parent: InputMaybe;
+ readonly title: InputMaybe;
+ readonly url: InputMaybe;
+};
+
export enum FieldSelectorEnum {
Select = 0
}
@@ -648,6 +778,8 @@ export type File = Node & {
readonly childArticlesYaml: Maybe;
/** Returns the first child node of type CertificationsYaml or null if there are no children of given type on this node */
readonly childCertificationsYaml: Maybe;
+ /** Returns the first child node of type FeaturedYaml or null if there are no children of given type on this node */
+ readonly childFeaturedYaml: Maybe;
/** Returns the first child node of type HistoriesYaml or null if there are no children of given type on this node */
readonly childHistoriesYaml: Maybe;
/** Returns the first child node of type Mdx or null if there are no children of given type on this node */
@@ -665,6 +797,8 @@ export type File = Node & {
readonly childrenArticlesYaml: Maybe>>;
/** Returns all children nodes filtered by type CertificationsYaml */
readonly childrenCertificationsYaml: Maybe>>;
+ /** Returns all children nodes filtered by type FeaturedYaml */
+ readonly childrenFeaturedYaml: Maybe>>;
/** Returns all children nodes filtered by type HistoriesYaml */
readonly childrenHistoriesYaml: Maybe>>;
/** Returns all children nodes filtered by type Mdx */
@@ -821,6 +955,7 @@ export type FileFieldSelector = {
readonly changeTime: InputMaybe;
readonly childArticlesYaml: InputMaybe;
readonly childCertificationsYaml: InputMaybe;
+ readonly childFeaturedYaml: InputMaybe;
readonly childHistoriesYaml: InputMaybe;
readonly childMdx: InputMaybe;
readonly childNotesYaml: InputMaybe;
@@ -830,6 +965,7 @@ export type FileFieldSelector = {
readonly children: InputMaybe;
readonly childrenArticlesYaml: InputMaybe;
readonly childrenCertificationsYaml: InputMaybe;
+ readonly childrenFeaturedYaml: InputMaybe;
readonly childrenHistoriesYaml: InputMaybe;
readonly childrenMdx: InputMaybe;
readonly childrenNotesYaml: InputMaybe;
@@ -878,6 +1014,7 @@ export type FileFilterInput = {
readonly changeTime: InputMaybe;
readonly childArticlesYaml: InputMaybe;
readonly childCertificationsYaml: InputMaybe;
+ readonly childFeaturedYaml: InputMaybe;
readonly childHistoriesYaml: InputMaybe;
readonly childMdx: InputMaybe;
readonly childNotesYaml: InputMaybe;
@@ -887,6 +1024,7 @@ export type FileFilterInput = {
readonly children: InputMaybe;
readonly childrenArticlesYaml: InputMaybe;
readonly childrenCertificationsYaml: InputMaybe;
+ readonly childrenFeaturedYaml: InputMaybe;
readonly childrenHistoriesYaml: InputMaybe;
readonly childrenMdx: InputMaybe;
readonly childrenNotesYaml: InputMaybe;
@@ -976,6 +1114,7 @@ export type FileSortInput = {
readonly changeTime: InputMaybe;
readonly childArticlesYaml: InputMaybe;
readonly childCertificationsYaml: InputMaybe;
+ readonly childFeaturedYaml: InputMaybe;
readonly childHistoriesYaml: InputMaybe;
readonly childMdx: InputMaybe;
readonly childNotesYaml: InputMaybe;
@@ -985,6 +1124,7 @@ export type FileSortInput = {
readonly children: InputMaybe;
readonly childrenArticlesYaml: InputMaybe;
readonly childrenCertificationsYaml: InputMaybe;
+ readonly childrenFeaturedYaml: InputMaybe;
readonly childrenHistoriesYaml: InputMaybe;
readonly childrenMdx: InputMaybe;
readonly childrenNotesYaml: InputMaybe;
@@ -2378,6 +2518,7 @@ export type Query = {
readonly allArticlesYaml: ArticlesYamlConnection;
readonly allCertificationsYaml: CertificationsYamlConnection;
readonly allDirectory: DirectoryConnection;
+ readonly allFeaturedYaml: FeaturedYamlConnection;
readonly allFile: FileConnection;
readonly allHistoriesYaml: HistoriesYamlConnection;
readonly allHistory: HistoryConnection;
@@ -2398,6 +2539,7 @@ export type Query = {
readonly articlesYaml: Maybe;
readonly certificationsYaml: Maybe;
readonly directory: Maybe;
+ readonly featuredYaml: Maybe;
readonly file: Maybe;
readonly historiesYaml: Maybe;
readonly history: Maybe;
@@ -2442,6 +2584,14 @@ export type QueryAllDirectoryArgs = {
};
+export type QueryAllFeaturedYamlArgs = {
+ filter: InputMaybe;
+ limit: InputMaybe;
+ skip: InputMaybe;
+ sort: InputMaybe>>;
+};
+
+
export type QueryAllFileArgs = {
filter: InputMaybe;
limit: InputMaybe;
@@ -2642,6 +2792,17 @@ export type QueryDirectoryArgs = {
};
+export type QueryFeaturedYamlArgs = {
+ children: InputMaybe;
+ id: InputMaybe;
+ internal: InputMaybe;
+ ogImage: InputMaybe;
+ parent: InputMaybe;
+ title: InputMaybe;
+ url: InputMaybe;
+};
+
+
export type QueryFileArgs = {
absolutePath: InputMaybe;
accessTime: InputMaybe;
@@ -2656,6 +2817,7 @@ export type QueryFileArgs = {
changeTime: InputMaybe;
childArticlesYaml: InputMaybe;
childCertificationsYaml: InputMaybe;
+ childFeaturedYaml: InputMaybe;
childHistoriesYaml: InputMaybe;
childMdx: InputMaybe;
childNotesYaml: InputMaybe;
@@ -2665,6 +2827,7 @@ export type QueryFileArgs = {
children: InputMaybe;
childrenArticlesYaml: InputMaybe;
childrenCertificationsYaml: InputMaybe;
+ childrenFeaturedYaml: InputMaybe;
childrenHistoriesYaml: InputMaybe;
childrenMdx: InputMaybe;
childrenNotesYaml: InputMaybe;
@@ -4298,6 +4461,13 @@ export type TimelineVirtualizedListTimelineFragment = { readonly nodes: Readonly
& { dateX: SlidesYaml['date'] }
)> };
+export type FeaturedCardFragment = Pick;
+
+export type FeaturedListFragment = { readonly nodes: ReadonlyArray<(
+ { readonly __typename: 'FeaturedYaml' }
+ & Pick
+ )> };
+
export type UseSearchQueryVariables = Exact<{ [key: string]: never; }>;
@@ -4353,6 +4523,9 @@ export type IndexPageQuery = { readonly timelineItems: { readonly nodes: Readonl
{ readonly __typename: 'SlidesYaml' }
& Pick
& { dateX: SlidesYaml['date'] }
+ )> }, readonly featuredTimelineItems: { readonly nodes: ReadonlyArray<(
+ { readonly __typename: 'FeaturedYaml' }
+ & Pick
)> } };
export type OutputsPageQueryVariables = Exact<{ [key: string]: never; }>;
diff --git a/src/layouts/Footer.tsx b/src/layouts/Footer.tsx
index bc837ec1..bcdcc9cc 100644
--- a/src/layouts/Footer.tsx
+++ b/src/layouts/Footer.tsx
@@ -59,6 +59,8 @@ export const Footer = (): JSX.Element => {
src={happyBusy}
width={200}
height={40}
+ decoding="async"
+ loading="lazy"
/>
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 8e9aa894..32cc4c0e 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -10,10 +10,8 @@ import { InarticleAd } from "@/components/InarticleAd";
import { Spacer } from "@/components/Spacer";
import { SITE_METADATA } from "@/constants/SITE_METADATA";
import { BioCardList } from "@/features/Bio";
-import {
- TimelineVirtualizedList,
- TimelinePinnedList,
-} from "@/features/Timeline";
+import { TimelineVirtualizedList } from "@/features/Timeline";
+import { FeaturedList } from "@/features/TimelineFeatured";
import { TimelineTabList } from "@/features/TimelineTab";
import { HeadTemplate } from "@/layouts/HeadTemplate";
import { isDefined } from "@/utils/typeguard";
@@ -23,6 +21,9 @@ export const query = graphql`
timelineItems: allTimeline(sort: { date: DESC }) {
...TimelineVirtualizedListTimeline
}
+ featuredTimelineItems: allFeaturedYaml {
+ ...FeaturedList
+ }
}
`;
@@ -43,6 +44,7 @@ export const Head: HeadFC = ({ location }) => {
const IndexPage = ({ data }: PageProps): JSX.Element => {
const timelineItems = data.timelineItems;
+ const featuredTimelineItems = data.featuredTimelineItems;
return (
<>
@@ -53,7 +55,15 @@ const IndexPage = ({ data }: PageProps): JSX.Element => {
>
-
+
+ Featured
+
+
+
+
+
+ Timeline ({timelineItems.nodes.length})
+
@@ -65,7 +75,7 @@ const IndexPage = ({ data }: PageProps): JSX.Element => {