feat: added cover image for article

This commit is contained in:
Sergey Yarkov 2022-08-06 21:35:19 +03:00
parent 7c76b73c15
commit 1cbe9ea47e
8 changed files with 479 additions and 558 deletions

View File

@ -1,11 +1,12 @@
import { defineConfig } from "astro/config"; import { defineConfig } from "astro/config";
import solid from "@astrojs/solid-js";
import compress from "astro-compress";
import { h } from "hastscript"; import { h } from "hastscript";
import { toString } from "hast-util-to-string"; import { toString } from "hast-util-to-string";
import { escape } from "html-escaper"; import { escape } from "html-escaper";
import solid from "@astrojs/solid-js";
import image from "@astrojs/image";
import compress from "astro-compress";
const createAnchorLabel = (heading: string) => { const createAnchorLabel = (heading) => {
const node = h("span.anchor-label", escape(heading)); const node = h("span.anchor-label", escape(heading));
node.properties["is:raw"] = true; node.properties["is:raw"] = true;
return node; return node;
@ -14,7 +15,14 @@ const createAnchorLabel = (heading: string) => {
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
site: "https://yarkov.tech", site: "https://yarkov.tech",
integrations: [solid(), compress({ img: false, html: false })], integrations: [
solid(),
compress({
img: false,
html: false,
}),
image(),
],
markdown: { markdown: {
syntaxHighlight: "prism", syntaxHighlight: "prism",
remarkPlugins: ["remark-gfm", "remark-smartypants"], remarkPlugins: ["remark-gfm", "remark-smartypants"],

985
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -18,24 +18,25 @@
"lint": "eslint '**/*.{js,mjs,ts,tsx}'" "lint": "eslint '**/*.{js,mjs,ts,tsx}'"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/image": "^0.3.2",
"@astrojs/solid-js": "^0.4.1", "@astrojs/solid-js": "^0.4.1",
"@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/eslint-plugin": "^5.32.0",
"@typescript-eslint/parser": "^5.31.0", "@typescript-eslint/parser": "^5.32.0",
"astro": "^1.0.0-beta.73", "astro": "^1.0.0-rc.7",
"astro-compress": "^0.0.15", "astro-compress": "^0.0.15",
"astro-icon": "^0.7.3", "astro-icon": "^0.7.3",
"eslint": "^8.20.0", "eslint": "^8.21.0",
"eslint-plugin-solid": "^0.7.1", "eslint-plugin-solid": "^0.7.1",
"hast-util-to-string": "^2.0.0", "hast-util-to-string": "^2.0.0",
"hastscript": "^7.0.2", "hastscript": "^7.0.2",
"html-escaper": "^3.0.3", "html-escaper": "^3.0.3",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"prettier-plugin-astro": "^0.2.0", "prettier-plugin-astro": "^0.3.0",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1", "rehype-slug": "^5.0.1",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"remark-smartypants": "^2.0.0", "remark-smartypants": "^2.0.0",
"sass": "^1.54.0", "sass": "^1.54.3",
"solid-js": "^1.4.8" "solid-js": "^1.4.8"
} }
} }

View File

@ -1,6 +1,6 @@
import { Component } from 'solid-js'; import type { Component } from "solid-js";
import { DateFormatter } from '@utils/date'; import { DateFormatter } from "@utils/date";
import './ArticleItem.scss'; import "./ArticleItem.scss";
export type ArticleItemProps = { export type ArticleItemProps = {
data: ArticleType; data: ArticleType;
@ -9,7 +9,7 @@ export type ArticleItemProps = {
export const ArticleItem: Component<ArticleItemProps> = (props) => { export const ArticleItem: Component<ArticleItemProps> = (props) => {
return ( return (
<article class="article-item"> <article class="article-item">
<a href={`/blog/${new Date(props.data.published_at).toLocaleDateString('en-CA')}/${props.data.slug}`}> <a href={`/blog/${new Date(props.data.published_at).toLocaleDateString("en-CA")}/${props.data.slug}`}>
<h3>{props.data.title}</h3> <h3>{props.data.title}</h3>
<p> <p>
<time datetime={props.data.published_at.toString()}>{DateFormatter.format(new Date(props.data.published_at))}</time> <time datetime={props.data.published_at.toString()}>{DateFormatter.format(new Date(props.data.published_at))}</time>

View File

@ -1,8 +1,9 @@
--- ---
import { DateFormatter } from "@root/utils"; import { DateFormatter } from "@root/utils";
import { Image, Picture } from '@astrojs/image/components'
import "./ArticlePost.scss"; import "./ArticlePost.scss";
export interface Props { export type Props = {
data: ArticleType; data: ArticleType;
} }
@ -28,11 +29,11 @@ const { title, tags, author, published_at } = data;
<time datetime={published_at}>{DateFormatter.format(new Date(published_at))}</time> <time datetime={published_at}>{DateFormatter.format(new Date(published_at))}</time>
<span>{author}</span> <span>{author}</span>
</div> </div>
<div> {data.coverImage && <div>
<figure> <figure>
<img src="https://picsum.photos/1920/1080" alt="Article Image" /> <Image src={data.coverImage} width={700} height={400} aspectRatio={'16:9'} format={'webp'} alt={data.title} />
</figure> </figure>
</div> </div>}
</header> </header>
<slot /> <slot />
<footer> <footer>

View File

@ -20,7 +20,7 @@
& ul { & ul {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
column-gap: 5px; column-gap: 7px;
row-gap: 7px; row-gap: 7px;
} }
} }
@ -38,6 +38,7 @@
display: block; display: block;
margin: 0 auto; margin: 0 auto;
max-width: 100%; max-width: 100%;
height: auto;
} }
} }
} }

1
src/types/main.d.ts vendored
View File

@ -37,6 +37,7 @@ declare global {
type ArticleType = { type ArticleType = {
slug: string; slug: string;
title: string; title: string;
coverImage?: string | undefined;
description: string; description: string;
author: string; author: string;
tags: Array<string>; tags: Array<string>;

View File

@ -5,7 +5,7 @@
"moduleResolution": "node", "moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"types": ["vite/client"], "types": ["vite/client", "@astrojs/image/client"],
"sourceMap": true, "sourceMap": true,
"baseUrl": ".", "baseUrl": ".",
"jsx": "preserve", "jsx": "preserve",