diff --git a/package.json b/package.json
index 84533f1..5c86197 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
"graphql-request": "^6.0.0",
"next": "13.3.0",
"react": "18.2.0",
+ "react-blurhash": "^0.3.0",
"react-dom": "18.2.0",
"react-imgix": "^9.7.0",
"typescript": "5.0.4"
diff --git a/src/components/Post/Post.tsx b/src/components/Post/Post.tsx
index c196d8f..5d54966 100644
--- a/src/components/Post/Post.tsx
+++ b/src/components/Post/Post.tsx
@@ -12,6 +12,7 @@ import {
import { Authors } from '../Authors'
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
import { Tags } from '@/components/Tags'
+import { ResponsiveImage } from '../ResponsiveImage/ResponsiveImage'
export enum PostImageRatio {
PORTRAIT = 'portrait',
@@ -121,7 +122,8 @@ export default function Post({
if (postType === 'body') {
return (
-
+
+ {/**/}
)
} else {
@@ -198,6 +200,7 @@ const ThumbnailContainer = styled.div<{
width: 100%;
height: 100%;
max-height: 458px; // temporary max-height based on the Figma design's max height
+ overflow: hidden;
`
const Thumbnail = styled(Image)`
diff --git a/src/components/ResponsiveImage/ResponsiveImage.tsx b/src/components/ResponsiveImage/ResponsiveImage.tsx
index d57fa48..58b8848 100644
--- a/src/components/ResponsiveImage/ResponsiveImage.tsx
+++ b/src/components/ResponsiveImage/ResponsiveImage.tsx
@@ -1,22 +1,61 @@
-import React from 'react'
+import React, { useState } from 'react'
import Image from 'next/image'
import { UnbodyImageBlock } from '@/lib/unbody/unbody.types'
import Imgix from 'react-imgix'
+import styled from '@emotion/styled'
+import { Blurhash } from 'react-blurhash'
type Props = {
data: UnbodyImageBlock
+ height?: number | string
}
-export const ResponsiveImage = ({ data }: Props) => {
+export const ResponsiveImage = ({ data, height = '100%' }: Props) => {
+ const [loaded, setLoaded] = useState(false)
+
return (
-
+
+ {/**/}
+
+
)
}
+
+const Container = styled.div`
+ position: relative;
+ width: 100%;
+ padding-top: 100%;
+ overflow: hidden;
+ object-fit: cover;
+
+ filter: grayscale(100%);
+ transition: filter 0.1s ease-in-out;
+
+ :hover {
+ filter: grayscale(0%);
+ }
+
+ > * {
+ position: absolute !important;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+
+ &:last-of-type {
+ //opacity: 0.5;
+ //&.loaded{
+ // opacity: 1;
+ //}
+ }
+ }
+`
diff --git a/src/configs/data.configs.ts b/src/configs/data.configs.ts
new file mode 100644
index 0000000..ff381a3
--- /dev/null
+++ b/src/configs/data.configs.ts
@@ -0,0 +1,8 @@
+export const ArticleBlocksOrders = {
+ title: 0,
+ subtitle: 1,
+ summary: 2,
+ tags: 3,
+ mentions: 4,
+ cover: 5,
+}
diff --git a/src/lib/unbody/unbody.types.ts b/src/lib/unbody/unbody.types.ts
index 153b621..0cdc8d6 100644
--- a/src/lib/unbody/unbody.types.ts
+++ b/src/lib/unbody/unbody.types.ts
@@ -20,6 +20,10 @@ export type TextBlockEnhanced = UnbodyTextBlock & {
document?: Array
}
+export type ImageBlockEnhanced = UnbodyImageBlock & {
+ blurhash?: string
+}
+
export * as UnbodyGraphQl from './unbody-content.types'
export type UnbodyGraphQlResponse = {
diff --git a/src/lib/unbody/unbody.utils.ts b/src/lib/unbody/unbody.utils.ts
index d578c93..81d1236 100644
--- a/src/lib/unbody/unbody.utils.ts
+++ b/src/lib/unbody/unbody.utils.ts
@@ -1,8 +1,18 @@
-import { UnbodyGetFilters } from './unbody.types'
+import { ImageBlockEnhanced, UnbodyGetFilters } from './unbody.types'
import { UnbodyGraphQl } from './unbody-content.types'
+import axios from 'axios'
const operators = Object.values(UnbodyGraphQl.Filters.WhereOperatorEnum)
+// export const enhanceImageBlock = async (block: UnbodyGraphQl.ImageBlock): Promise => {
+// try{
+// const blurHash = axios.get(`${block.url}?fm=blurhash`).then((res) => res.data)
+// console.log(blurHash)
+// }catch(e){
+// console.log(e)
+// }
+// }
+
export const parseFilterArgs = (args: UnbodyGetFilters = {}): string => {
const parse = (obj: any): string | number => {
if (typeof obj === 'number') {
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 7eb851a..4489db0 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -48,14 +48,26 @@ export default function App({ Component, pageProps }: AppLayoutProps) {
width: 100%;
height: 100%;
}
+
#__next {
max-width: 1440px;
margin-left: auto;
margin-right: auto;
}
+
:root {
--lpe-nav-rendered-height: ${uiConfigs.navbarRenderedHeight}px;
}
+
+ //.lazyload,
+ //img.lazyloading {
+ // opacity: 0;
+ // transition: opacity 4000ms;
+ //}
+ //
+ //img.lazyloaded {
+ // opacity: 1;
+ //}
`}
/>
diff --git a/src/queries/getPosts.ts b/src/queries/getPosts.ts
index 72627d1..760bdd8 100644
--- a/src/queries/getPosts.ts
+++ b/src/queries/getPosts.ts
@@ -25,6 +25,8 @@ export const getHomePagePostsQuery = (args: UnbodyGetFilters = defaultArgs) =>
url
alt
order
+ width
+ height
__typename
}
}
diff --git a/src/queries/searchArticles.ts b/src/queries/searchArticles.ts
index 9df9c29..26f1749 100644
--- a/src/queries/searchArticles.ts
+++ b/src/queries/searchArticles.ts
@@ -17,6 +17,8 @@ export const getSearchArticlesQuery = (args: UnbodyGetFilters = defaultArgs) =>
url
alt
order
+ width
+ height
__typename
}
}
diff --git a/src/utils/data.utils.ts b/src/utils/data.utils.ts
index e33597f..97e6f1d 100644
--- a/src/utils/data.utils.ts
+++ b/src/utils/data.utils.ts
@@ -8,6 +8,7 @@ import {
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
import { isAuthorsParagraph } from './html.utils'
import { similarity } from './string.utils'
+import { ArticleBlocksOrders } from '@/configs/data.configs'
function hasClassName(inputString: string, className: string) {
const regex = new RegExp(`class\\s*=\\s*"[^"]*\\b${className}\\b[^"]*"`)
@@ -32,15 +33,19 @@ export const getBodyBlocks = ({
const isTitle = classNames.includes('title')
const isSubtitle = classNames.includes('subtitle')
+
const isCoverImage =
- b.order === 4 &&
+ b.order === ArticleBlocksOrders.cover &&
b.__typename === UnbodyGraphQl.UnbodyDocumentTypeNames.ImageBlock
+
const isAuthor =
b.__typename === UnbodyGraphQl.UnbodyDocumentTypeNames.TextBlock &&
similarity(b.text, mentions.map((m) => m.name).join('')) > 0.8
+
const isSummary =
b.__typename === UnbodyGraphQl.UnbodyDocumentTypeNames.TextBlock &&
summary === b.text
+
const isTag =
b.__typename === UnbodyGraphQl.UnbodyDocumentTypeNames.TextBlock &&
similarity(b.text, tags.map((t) => `#${t}`).join(' ')) > 0.8
@@ -69,7 +74,7 @@ export const getArticleCover = (
return (
((blocks || []).find(
(b) =>
- b.order === 4 &&
+ b.order === ArticleBlocksOrders.cover &&
b.__typename === UnbodyGraphQl.UnbodyDocumentTypeNames.ImageBlock,
) as UnbodyImageBlock) || null
)
diff --git a/yarn.lock b/yarn.lock
index c77a9d8..603c3ee 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2539,6 +2539,11 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+react-blurhash@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/react-blurhash/-/react-blurhash-0.3.0.tgz#f125801d052644f74420c79b05981691d17c9705"
+ integrity sha512-XlKr4Ns1iYFRnk6DkAblNbAwN/bTJvxTVoxMvmTcURdc5oLoXZwqAF9N3LZUh/HT+QFlq5n6IS6VsDGsviYAiQ==
+
react-dom@18.2.0, react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"