From e8d619c57e801364ac6f7352ad5ee53ed70e236b Mon Sep 17 00:00:00 2001 From: Chen Junda Date: Mon, 23 Mar 2020 23:58:04 +0800 Subject: [PATCH] update published_time on article page --- src/pages/index.tsx | 312 +++++++++++------------ src/templates/ArticlePageTemplate.tsx | 341 +++++++++++++------------- 2 files changed, 331 insertions(+), 322 deletions(-) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9a8be66..89ffa74 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,152 +1,160 @@ -import React from "react"; - -import Contacts from "@/components/Contacts"; -import { RootContainer, InnerContainer } from "@/layouts/LayeredLayout"; -import bgImg from "~/assets/mainbg.jpg"; -import lang from "@/i18n/lang"; -import LocalizedString from "@/i18n/LocalizedString"; -import { FaFile, FaBookOpen, FaMale, FaClock, FaSlideshare, FaRss } from "react-icons/fa"; -import { Link } from "gatsby"; -import I18nStore from "@/stores/I18nStore"; -import { useStore } from "simstate"; -import MetadataStore from "@/stores/MetadataStore"; -import HeaderFooterLayout from "@/layouts/HeaderFooterLayout"; -import styled from "styled-components"; -import { colors } from "@/styles/variables"; -import moveInAnimation from "@/styles/moveInAnimation"; -import isServer from "@/utils/isServer"; -import { PageMetadata } from "@/components/PageMetadata"; - -const Bg = styled(RootContainer)` - height: 100vh; - - background-color: ${colors.homepageBgColor}; - background-image: url(${bgImg}); - - /* Center and scale the image nicely */ - background-position: center; - background-repeat: no-repeat; - background-size: cover; - - display: flex; - align-items: center; - justify-items: center; - justify-content: center; - -`; - -const TextContent = styled(InnerContainer)` - z-index: 3; - color: white; - text-align: center; - - & > * { - padding: 12px 0; - } - animation: ${moveInAnimation} 0.2s ease-in-out; - -`; - - -const TitleText = styled.h1` - -`; - -const Slogan = styled.h4` -`; - -const LinkContainer = styled.div` - - & > * { - margin: 4px; - } -`; - -const root = lang.homepage; - -const Button: React.FC<{ to: string; mode?: "to" | "href" }> = ({ to, mode = "to", children }) => { - - const metadataStore = useStore(MetadataStore); - const i18nStore = useStore(I18nStore); - - const commonProps = { - className: "btn btn-info", - key: to, - }; - - if (mode === "to") { - return ( - - {children} - - ) - } else { - return ( - - {children} - - ); - } -}; - - -const links = [ - ["/rss.xml", FaRss, root.links.rss, "href"], - ["resume", FaFile, root.links.resume], - ["/slides", FaSlideshare, root.links.slides], - ["about-me", FaMale, root.links.aboutMe], -] as const; - -function selectDate(): string { - const hour = new Date().getHours(); - if (hour >= 6 && hour <= 11) { - return root.morning; - } else if (hour >= 12 && hour <= 17) { - return root.afternoon; - } else { - return root.evening; - } -} - -const HomePage: React.FunctionComponent = () => { - - const metadataStore = useStore(MetadataStore); - - return ( - - - - - {isServer() ? "" : } - - - - {links.map(([to, Icon, id, mode = "to"]) => ( - - ))} - - -

- - : - {metadataStore.siteMetadata.formattedLastUpdate} -

-
- -
-
- ); -} - -export default HomePage; +import React from "react"; + +import Contacts from "@/components/Contacts"; +import { RootContainer, InnerContainer } from "@/layouts/LayeredLayout"; +import bgImg from "~/assets/mainbg.jpg"; +import lang from "@/i18n/lang"; +import LocalizedString from "@/i18n/LocalizedString"; +import { FaFile, FaBookOpen, FaMale, FaClock, FaSlideshare, FaRss } from "react-icons/fa"; +import { Link } from "gatsby"; +import I18nStore from "@/stores/I18nStore"; +import { useStore } from "simstate"; +import MetadataStore from "@/stores/MetadataStore"; +import HeaderFooterLayout from "@/layouts/HeaderFooterLayout"; +import styled from "styled-components"; +import { colors } from "@/styles/variables"; +import moveInAnimation from "@/styles/moveInAnimation"; +import isServer from "@/utils/isServer"; +import { PageMetadata } from "@/components/PageMetadata"; + +const Bg = styled(RootContainer)` + height: 100vh; + + background-color: ${colors.homepageBgColor}; + background-image: url(${bgImg}); + + /* Center and scale the image nicely */ + background-position: center; + background-repeat: no-repeat; + background-size: cover; + + display: flex; + align-items: center; + justify-items: center; + justify-content: center; + +`; + +const TextContent = styled(InnerContainer)` + z-index: 3; + color: white; + text-align: center; + + & > * { + padding: 12px 0; + } + animation: ${moveInAnimation} 0.2s ease-in-out; + +`; + + +const TitleText = styled.h1` + +`; + +const Slogan = styled.h4` +`; + +const LinkContainer = styled.div` + + & > * { + margin: 4px; + } +`; + +const root = lang.homepage; + +const Button: React.FC<{ to: string; mode?: "to" | "href" }> = ({ to, mode = "to", children }) => { + + const metadataStore = useStore(MetadataStore); + const i18nStore = useStore(I18nStore); + + const commonProps = { + className: "btn btn-info", + key: to, + }; + + if (mode === "to") { + return ( + + {children} + + ) + } else { + return ( + + {children} + + ); + } +}; + + +const links = [ + ["/rss.xml", FaRss, root.links.rss, "href"], + ["resume", FaFile, root.links.resume], + ["/slides", FaSlideshare, root.links.slides], + ["about-me", FaMale, root.links.aboutMe], +] as const; + +const key = { + a: ["b", "c"], + c: ["d", "c"], +} as const; + +type Keys = { [k in keyof typeof key]: k[0] }; + + +function selectDate(): string { + const hour = new Date().getHours(); + if (hour >= 6 && hour <= 11) { + return root.morning; + } else if (hour >= 12 && hour <= 17) { + return root.afternoon; + } else { + return root.evening; + } +} + +const HomePage: React.FunctionComponent = () => { + + const metadataStore = useStore(MetadataStore); + + return ( + + + + + {isServer() ? "" : } + + + + {links.map(([to, Icon, id, mode = "to"]) => ( + + ))} + + +

+ + : + {metadataStore.siteMetadata.formattedLastUpdate} +

+
+ +
+
+ ); +} + +export default HomePage; diff --git a/src/templates/ArticlePageTemplate.tsx b/src/templates/ArticlePageTemplate.tsx index 9fdb59f..015a5f2 100644 --- a/src/templates/ArticlePageTemplate.tsx +++ b/src/templates/ArticlePageTemplate.tsx @@ -1,170 +1,171 @@ -import React, { useEffect } from "react"; -import Page from "@/layouts/Page"; -import CommentPanel from "@/components/Article/CommentPanel"; -import { ArticleNode, Heading } from "@/models/ArticleNode"; - -import MetadataStore from "@/stores/MetadataStore"; -import I18nStore from "@/stores/I18nStore"; -import TocPanel from "@/components/Article/TocPanel"; -import { Row, Col } from "reactstrap"; -import ArticleContentDisplay from "@/components/Article/ContentDisplay"; -import { HtmlAst } from "@/models/HtmlAst"; -import ArticlePageBanner from "@/components/Article/ArticlePageBanner"; -import { useStore } from "simstate"; -import ArticleStore from "@/stores/ArticleStore"; -import styled, { keyframes } from "styled-components"; -import HeaderFooterLayout from "@/layouts/HeaderFooterLayout"; -import RelatedArticles from "@/components/Article/RelatedArticles"; -import { heights } from "@/styles/variables"; -import BannerLayout from "@/layouts/BannerLayout"; -import { getLanguage } from "@/i18n/definition"; -import { PageMetadata } from "@/components/PageMetadata"; - -interface Props { - pageContext: { - id: string; - lang: string; - htmlAst: HtmlAst; - headings: Heading[]; - }; - location: Location; -} - - -const enterAnimation = keyframes` - from { - opacity: 0; - } - - to { - opacity: 1; - } -`; - -const PageWithHeader = styled(Page)` - animation: ${enterAnimation} 0.2s ease-in-out; -`; - -const PageComponent: React.FC<{ hasHeader: boolean; children: React.ReactNode }> = ({ hasHeader, children }) => { - return hasHeader ? {children} : {children}; -}; - -const RootLayout: React.FC<{ article: ArticleNode; lang: string }> = ({ article, children, lang }) => { - - const { - frontmatter: { - id, title, date, tags, hide_heading, - }, timeToRead } = article; - - if (hide_heading) { - return ( - - {children} - - ); - } else { - return ( - - }> - {children} - - ); - } -} - -const ArticlePageTemplate: React.FC = (props) => { - - const i18nStore = useStore(I18nStore); - const metadataStore = useStore(MetadataStore); - const articleStore = useStore(ArticleStore); - - const { id, lang, htmlAst, headings } = props.pageContext; - - const language = getLanguage(lang); - - const articleNode = metadataStore.getArticleOfLang(id, language); - - useEffect(() => { - articleStore.setArticle(articleNode); - return () => { - articleStore.setArticle(null); - }; - }, [articleNode]); - - const { path, excerpt, frontmatter: { - title, date, tags, hide_heading, no_toc, related, - } } = articleNode; - - const langPathMap = metadataStore.getLangPathMap(props.pageContext.id); - - return ( - -
- ({ - name: "og:article:tag", - content: x, - })), - ...Object.keys(langPathMap) - .filter((x) => x !== lang) - .map((x) => ({ - name: "og:locale:alternate", - content: getLanguage(x).metadata.detailedId, - })), - ]} - /> - - - - - - { - !no_toc - && ( - - - - - - ) - } - - - {/* */} - {related ? : null} -
- -
-
-
- ); -} - -export default ArticlePageTemplate; - -const StickySidePanel = styled.div` - position: sticky; - top: ${heights.header + 32}px; -`; +import React, { useEffect } from "react"; +import Page from "@/layouts/Page"; +import CommentPanel from "@/components/Article/CommentPanel"; +import { ArticleNode, Heading } from "@/models/ArticleNode"; + +import MetadataStore from "@/stores/MetadataStore"; +import I18nStore from "@/stores/I18nStore"; +import TocPanel from "@/components/Article/TocPanel"; +import { Row, Col } from "reactstrap"; +import ArticleContentDisplay from "@/components/Article/ContentDisplay"; +import { HtmlAst } from "@/models/HtmlAst"; +import ArticlePageBanner from "@/components/Article/ArticlePageBanner"; +import { useStore } from "simstate"; +import ArticleStore from "@/stores/ArticleStore"; +import styled, { keyframes } from "styled-components"; +import HeaderFooterLayout from "@/layouts/HeaderFooterLayout"; +import RelatedArticles from "@/components/Article/RelatedArticles"; +import { heights } from "@/styles/variables"; +import BannerLayout from "@/layouts/BannerLayout"; +import { getLanguage } from "@/i18n/definition"; +import { PageMetadata } from "@/components/PageMetadata"; +import { DateTime } from "luxon"; + +interface Props { + pageContext: { + id: string; + lang: string; + htmlAst: HtmlAst; + headings: Heading[]; + }; + location: Location; +} + + +const enterAnimation = keyframes` + from { + opacity: 0; + } + + to { + opacity: 1; + } +`; + +const PageWithHeader = styled(Page)` + animation: ${enterAnimation} 0.2s ease-in-out; +`; + +const PageComponent: React.FC<{ hasHeader: boolean; children: React.ReactNode }> = ({ hasHeader, children }) => { + return hasHeader ? {children} : {children}; +}; + +const RootLayout: React.FC<{ article: ArticleNode; lang: string }> = ({ article, children, lang }) => { + + const { + frontmatter: { + id, title, date, tags, hide_heading, + }, timeToRead } = article; + + if (hide_heading) { + return ( + + {children} + + ); + } else { + return ( + + }> + {children} + + ); + } +} + +const ArticlePageTemplate: React.FC = (props) => { + + const i18nStore = useStore(I18nStore); + const metadataStore = useStore(MetadataStore); + const articleStore = useStore(ArticleStore); + + const { id, lang, htmlAst, headings } = props.pageContext; + + const language = getLanguage(lang); + + const articleNode = metadataStore.getArticleOfLang(id, language); + + useEffect(() => { + articleStore.setArticle(articleNode); + return () => { + articleStore.setArticle(null); + }; + }, [articleNode]); + + const { path, excerpt, frontmatter: { + title, date, tags, hide_heading, no_toc, related, + } } = articleNode; + + const langPathMap = metadataStore.getLangPathMap(props.pageContext.id); + + return ( + +
+ ({ + name: "og:article:tag", + content: x, + })), + ...Object.keys(langPathMap) + .filter((x) => x !== lang) + .map((x) => ({ + name: "og:locale:alternate", + content: getLanguage(x).metadata.detailedId, + })), + ]} + /> + + + + + + { + !no_toc + && ( + + + + + + ) + } + + + {/* */} + {related ? : null} +
+ +
+
+
+ ); +} + +export default ArticlePageTemplate; + +const StickySidePanel = styled.div` + position: sticky; + top: ${heights.header + 32}px; +`;