From 7777188a0e1be8719e01669c6ca1f6f3960319d0 Mon Sep 17 00:00:00 2001 From: Mike Velko <44818580+mikevelko@users.noreply.github.com> Date: Thu, 26 Sep 2024 23:28:15 +0200 Subject: [PATCH] blurhash (#125) * blurhash --- package.json | 1 + pnpm-lock.yaml | 21 ++++++++++++++++--- proto | 2 +- src/api/proto-http/common/index.ts | 7 +++++++ src/api/proto-http/frontend/index.ts | 21 ++++++++++++------- src/app/invoices/crypto/[uuid]/page.tsx | 6 +++--- src/components/sections/AdsSection.tsx | 1 + src/components/sections/Cart/CartItemRow.tsx | 5 +++-- src/components/sections/Header/index.tsx | 3 +-- src/components/sections/HeroSection.tsx | 1 + .../ProductsGridSection/ProductItem.tsx | 3 ++- src/components/ui/Image/index.tsx | 8 ++++--- 12 files changed, 57 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index b94374e5..deb5fac8 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@radix-ui/react-slot": "^1.0.2", "@react-input/mask": "^1.2.5", "@uidotdev/usehooks": "^2.4.1", + "blurhash-base64": "^0.0.3", "clsx": "2.1.0", "next": "15.0.0-canary.6", "qrcode": "^1.5.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01c3f923..f08675de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: '@uidotdev/usehooks': specifier: ^2.4.1 version: 2.4.1(react-dom@19.0.0-rc-6d3110b4d9-20240531(react@19.0.0-rc-6d3110b4d9-20240531))(react@19.0.0-rc-6d3110b4d9-20240531) + blurhash-base64: + specifier: ^0.0.3 + version: 0.0.3 clsx: specifier: 2.1.0 version: 2.1.0 @@ -2732,6 +2735,12 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + blurhash-base64@0.0.3: + resolution: {integrity: sha512-9cK+r4IZ73Bn6ee2ukHhURAkYX/aMvpHzuZHAe+y0mPqc2rsjpUwHBAv0HHHaOkeneQF+Odt1Qfps2K1wm7r5w==} + + blurhash@2.0.5: + resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==} + bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} @@ -9947,6 +9956,12 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + blurhash-base64@0.0.3: + dependencies: + blurhash: 2.0.5 + + blurhash@2.0.5: {} + bn.js@4.12.0: {} bn.js@5.2.1: {} @@ -10803,7 +10818,7 @@ snapshots: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -10827,7 +10842,7 @@ snapshots: enhanced-resolve: 5.16.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.3 is-core-module: 2.13.1 @@ -10849,7 +10864,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 diff --git a/proto b/proto index 982eed10..50dc9a99 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 982eed109c9a6942c08aadb794dea82d962dedfe +Subproject commit 50dc9a9972473a23e408c5b7ce16416f9b6dcb2c diff --git a/src/api/proto-http/common/index.ts b/src/api/proto-http/common/index.ts index 36bfa296..5f9a13e3 100644 --- a/src/api/proto-http/common/index.ts +++ b/src/api/proto-http/common/index.ts @@ -23,6 +23,8 @@ export type MediaItem = { thumbnail: MediaInfo | undefined; // Compressed media URL compressed: MediaInfo | undefined; + // BlurHash + blurhash: string | undefined; }; export type MediaInfo = { @@ -126,6 +128,7 @@ export type CategoryEnum = | "CATEGORY_ENUM_GLOVES" | "CATEGORY_ENUM_SHOES" | "CATEGORY_ENUM_BELT" + | "CATEGORY_ENUM_BAG" | "CATEGORY_ENUM_OTHER"; export type SizeEnum = | "SIZE_ENUM_UNKNOWN" @@ -348,7 +351,9 @@ export type FilterConditions = { export type PaymentMethodNameEnum = | "PAYMENT_METHOD_NAME_ENUM_UNKNOWN" | "PAYMENT_METHOD_NAME_ENUM_CARD" + | "PAYMENT_METHOD_NAME_ENUM_CARD_TEST" | "PAYMENT_METHOD_NAME_ENUM_ETH" + | "PAYMENT_METHOD_NAME_ENUM_ETH_TEST" | "PAYMENT_METHOD_NAME_ENUM_USDT_TRON" | "PAYMENT_METHOD_NAME_ENUM_USDT_SHASTA"; // Payment represents the payment table @@ -365,6 +370,7 @@ export type PaymentInsert = { transactionAmountPaymentCurrency: googletype_Decimal | undefined; payer: string | undefined; payee: string | undefined; + clientSecret: string | undefined; isTransactionDone: boolean | undefined; }; @@ -463,6 +469,7 @@ export type OrderItem = { id: number | undefined; orderId: number | undefined; thumbnail: string | undefined; + blurhash: string | undefined; productName: string | undefined; productPrice: string | undefined; productPriceWithSale: string | undefined; diff --git a/src/api/proto-http/frontend/index.ts b/src/api/proto-http/frontend/index.ts index 8a94f476..a0462458 100644 --- a/src/api/proto-http/frontend/index.ts +++ b/src/api/proto-http/frontend/index.ts @@ -46,6 +46,8 @@ export type common_MediaItem = { thumbnail: common_MediaInfo | undefined; // Compressed media URL compressed: common_MediaInfo | undefined; + // BlurHash + blurhash: string | undefined; }; export type common_MediaInfo = { @@ -185,6 +187,7 @@ export type common_CategoryEnum = | "CATEGORY_ENUM_GLOVES" | "CATEGORY_ENUM_SHOES" | "CATEGORY_ENUM_BELT" + | "CATEGORY_ENUM_BAG" | "CATEGORY_ENUM_OTHER"; export type common_MeasurementName = { id: number | undefined; @@ -227,7 +230,9 @@ export type common_PaymentMethod = { export type common_PaymentMethodNameEnum = | "PAYMENT_METHOD_NAME_ENUM_UNKNOWN" | "PAYMENT_METHOD_NAME_ENUM_CARD" + | "PAYMENT_METHOD_NAME_ENUM_CARD_TEST" | "PAYMENT_METHOD_NAME_ENUM_ETH" + | "PAYMENT_METHOD_NAME_ENUM_ETH_TEST" | "PAYMENT_METHOD_NAME_ENUM_USDT_TRON" | "PAYMENT_METHOD_NAME_ENUM_USDT_SHASTA"; export type common_ShipmentCarrier = { @@ -414,6 +419,7 @@ export type common_PaymentInsert = { transactionAmountPaymentCurrency: googletype_Decimal | undefined; payer: string | undefined; payee: string | undefined; + clientSecret: string | undefined; isTransactionDone: boolean | undefined; }; @@ -450,6 +456,7 @@ export type common_OrderItem = { id: number | undefined; orderId: number | undefined; thumbnail: string | undefined; + blurhash: string | undefined; productName: string | undefined; productPrice: string | undefined; productPriceWithSale: string | undefined; @@ -542,11 +549,11 @@ export type CancelOrderInvoiceRequest = { export type CancelOrderInvoiceResponse = { }; -export type CheckCryptoPaymentRequest = { +export type CheckPaymentRequest = { orderUuid: string | undefined; }; -export type CheckCryptoPaymentResponse = { +export type CheckPaymentResponse = { payment: common_Payment | undefined; }; @@ -625,8 +632,8 @@ export interface FrontendService { GetOrderInvoice(request: GetOrderInvoiceRequest): Promise; // Cancel an invoice for the order CancelOrderInvoice(request: CancelOrderInvoiceRequest): Promise; - // CheckCryptoPayment checks the crypto payment if it has been received and updates the order status if it has been received - CheckCryptoPayment(request: CheckCryptoPaymentRequest): Promise; + // CheckPayment checks the crypto payment if it has been received and updates the order status if it has been received + CheckPayment(request: CheckPaymentRequest): Promise; // Subscribe to the newsletter SubscribeNewsletter(request: SubscribeNewsletterRequest): Promise; // Unsubscribe from the newsletter @@ -872,7 +879,7 @@ export function createFrontendServiceClient( method: "CancelOrderInvoice", }) as Promise; }, - CheckCryptoPayment(request) { // eslint-disable-line @typescript-eslint/no-unused-vars + CheckPayment(request) { // eslint-disable-line @typescript-eslint/no-unused-vars if (!request.orderUuid) { throw new Error("missing required field request.order_uuid"); } @@ -889,8 +896,8 @@ export function createFrontendServiceClient( body, }, { service: "FrontendService", - method: "CheckCryptoPayment", - }) as Promise; + method: "CheckPayment", + }) as Promise; }, SubscribeNewsletter(request) { // eslint-disable-line @typescript-eslint/no-unused-vars const path = `api/frontend/newsletter/subscribe`; // eslint-disable-line quotes diff --git a/src/app/invoices/crypto/[uuid]/page.tsx b/src/app/invoices/crypto/[uuid]/page.tsx index cf475819..0e42e895 100644 --- a/src/app/invoices/crypto/[uuid]/page.tsx +++ b/src/app/invoices/crypto/[uuid]/page.tsx @@ -1,9 +1,9 @@ -import QRCode from "qrcode"; import CoreLayout from "@/components/layouts/CoreLayout"; import { serviceClient } from "@/lib/api"; +import QRCode from "qrcode"; -import V0GenUi from "./V0GenUi"; import { redirect } from "next/navigation"; +import V0GenUi from "./V0GenUi"; interface Props { params: { @@ -14,7 +14,7 @@ interface Props { export default async function Page({ params }: Props) { const { uuid } = params; - const cryptoPaymentInvoice = await serviceClient.CheckCryptoPayment({ + const cryptoPaymentInvoice = await serviceClient.CheckPayment({ orderUuid: uuid, }); diff --git a/src/components/sections/AdsSection.tsx b/src/components/sections/AdsSection.tsx index e897ff7a..6bae9c32 100644 --- a/src/components/sections/AdsSection.tsx +++ b/src/components/sections/AdsSection.tsx @@ -19,6 +19,7 @@ export default function AdsSection({ a?.media?.media?.fullSize.width, a?.media?.media?.fullSize.height, )} + blurHash={a?.media?.media?.blurhash} /> ) : null, diff --git a/src/components/sections/Cart/CartItemRow.tsx b/src/components/sections/Cart/CartItemRow.tsx index 26d6070a..fa316cb3 100644 --- a/src/components/sections/Cart/CartItemRow.tsx +++ b/src/components/sections/Cart/CartItemRow.tsx @@ -1,6 +1,6 @@ import { changeCartProductQuantity, removeCartProduct } from "@/actions/cart"; import type { common_OrderItem } from "@/api/proto-http/frontend"; -import ImageComponent from "@/components/ui/Image"; +import Image from "@/components/ui/Image"; import Size from "../Common/Size"; import ProductAmountButtons from "./ProductAmountButtons"; @@ -15,11 +15,12 @@ export default function CartItemRow({
-
diff --git a/src/components/sections/Header/index.tsx b/src/components/sections/Header/index.tsx index 20ce1399..765d1de6 100644 --- a/src/components/sections/Header/index.tsx +++ b/src/components/sections/Header/index.tsx @@ -1,9 +1,8 @@ "use client"; -import Link from "next/link"; import Image from "@/components/ui/Image"; +import Link from "next/link"; import useMobileMenu from "./useMobileMenu"; -import Button from "@/components/ui/Button"; export default function Header() { const { triggerElement, dropdownElement } = useMobileMenu(); diff --git a/src/components/sections/HeroSection.tsx b/src/components/sections/HeroSection.tsx index 8e67a7d8..357a2abb 100644 --- a/src/components/sections/HeroSection.tsx +++ b/src/components/sections/HeroSection.tsx @@ -12,6 +12,7 @@ export default function Hero({ media }: common_HeroItem) { src={media.media?.fullSize?.mediaUrl!} alt="main hero image" aspectRatio="4/3" + blurHash={media.media?.blurhash} />
diff --git a/src/components/sections/ProductsGridSection/ProductItem.tsx b/src/components/sections/ProductsGridSection/ProductItem.tsx index fefa7168..8cf31aee 100644 --- a/src/components/sections/ProductsGridSection/ProductItem.tsx +++ b/src/components/sections/ProductsGridSection/ProductItem.tsx @@ -1,6 +1,6 @@ import type { common_Product } from "@/api/proto-http/frontend"; -import Image from "@/components/ui/Image"; import Button from "@/components/ui/Button"; +import Image from "@/components/ui/Image"; import { CURRENCY_MAP } from "@/constants"; import { cn } from "@/lib/utils"; import Link from "next/link"; @@ -36,6 +36,7 @@ export default function ProductItem({ alt={product.productDisplay?.productBody?.name || ""} aspectRatio="4/3" // take from BE values fit="cover" + blurHash={product.productDisplay?.thumbnail?.media?.blurhash} />
diff --git a/src/components/ui/Image/index.tsx b/src/components/ui/Image/index.tsx index 8833cdb2..d1d14b2c 100644 --- a/src/components/ui/Image/index.tsx +++ b/src/components/ui/Image/index.tsx @@ -1,3 +1,4 @@ +import { blurhashToBase64 } from "blurhash-base64"; import Image from "next/image"; import ImageContainer from "./ImageContainer"; @@ -7,19 +8,18 @@ export default function ImageComponent({ alt, sizes = "(max-width: 1280px) 100vw, 1280px", fit, + blurHash, }: { alt: string; src: string; aspectRatio: string; sizes?: string; fit?: "cover" | "contain"; + blurHash?: string; }) { return ( {alt} );