From cc8ad07b8721ad70f47b89fbd69329009f44e100 Mon Sep 17 00:00:00 2001 From: Rob Cameron Date: Fri, 1 Mar 2024 11:28:36 -0800 Subject: [PATCH] Adds quality setting to useOgImage() --- .../src/components/__tests__/ogImage.test.ts | 55 ++++++++++++++----- packages/web/src/components/ogImage.tsx | 12 +++- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/packages/web/src/components/__tests__/ogImage.test.ts b/packages/web/src/components/__tests__/ogImage.test.ts index f06af4136c94..b09517b0f471 100644 --- a/packages/web/src/components/__tests__/ogImage.test.ts +++ b/packages/web/src/components/__tests__/ogImage.test.ts @@ -1,6 +1,6 @@ import '@testing-library/jest-dom/jest-globals' -import { useOgImageUrl, OGIMAGE_DEFAULTS } from '../ogImage' +import { useOgImage, OGIMAGE_DEFAULTS } from '../ogImage' const mockLocation = jest.fn() @@ -10,7 +10,7 @@ jest.mock('@redwoodjs/router', () => { } }) -describe('useOgImageUrl', () => { +describe('useOgImage', () => { afterEach(() => { jest.clearAllMocks() }) @@ -22,7 +22,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { url } = useOgImageUrl() + const { url } = useOgImage() expect(url).toBe('http://localhost/user/1.png') }) @@ -34,7 +34,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { width } = useOgImageUrl() + const { width } = useOgImage() expect(width).toBe(OGIMAGE_DEFAULTS.width) }) @@ -46,11 +46,23 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { height } = useOgImageUrl() + const { height } = useOgImage() expect(height).toBe(OGIMAGE_DEFAULTS.height) }) + it('returns the default quality of the image', () => { + mockLocation.mockReturnValue({ + origin: 'http://localhost/user/1', + pathname: '/user/1', + searchParams: new URLSearchParams(), + }) + + const { quality } = useOgImage() + + expect(quality).toBe(OGIMAGE_DEFAULTS.quality) + }) + it('returns all the props necessary to build the og:image meta tags', () => { mockLocation.mockReturnValue({ origin: 'http://localhost/user/1', @@ -58,7 +70,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { ogProps } = useOgImageUrl() + const { ogProps } = useOgImage() expect(ogProps).toEqual({ image: ['http://localhost/user/1.png', { width: 1200, height: 630 }], @@ -72,7 +84,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { url } = useOgImageUrl() + const { url } = useOgImage() expect(url).toBe('http://localhost/index.png') }) @@ -84,7 +96,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams('foo=bar'), }) - const { url } = useOgImageUrl() + const { url } = useOgImage() expect(url).toBe('http://localhost/about.png?foo=bar') }) @@ -96,7 +108,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { url } = useOgImageUrl({ extension: 'jpg' }) + const { url } = useOgImage({ extension: 'jpg' }) expect(url).toBe('http://localhost/user/1/edit.jpg') }) @@ -108,7 +120,7 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { url, width, height } = useOgImageUrl({ width: 1000 }) + const { url, width, height } = useOgImage({ width: 1000 }) expect(url).toBe('http://localhost/user/1.png?width=1000') expect(width).toBe(1000) @@ -122,13 +134,26 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams(), }) - const { url, width, height } = useOgImageUrl({ height: 500 }) + const { url, width, height } = useOgImage({ height: 500 }) expect(url).toBe('http://localhost/user/1.png?height=500') expect(width).toBe(OGIMAGE_DEFAULTS.width) expect(height).toBe(500) }) + it('allows setting a custom quality', () => { + mockLocation.mockReturnValue({ + origin: 'http://localhost/user/1', + pathname: '/user/1', + searchParams: new URLSearchParams(), + }) + + const { url, quality } = useOgImage({ quality: 50 }) + + expect(url).toBe('http://localhost/user/1.png?quality=50') + expect(quality).toBe(50) + }) + it('merges existing query variables with custom ones', () => { mockLocation.mockReturnValue({ origin: 'http://localhost/user/1', @@ -136,16 +161,18 @@ describe('useOgImageUrl', () => { searchParams: new URLSearchParams('foo=bar'), }) - const { url, width, height } = useOgImageUrl({ - extension: 'gif', + const { url, width, height, quality } = useOgImage({ + extension: 'png', width: 1024, height: 768, + quality: 75, }) expect(url).toBe( - 'http://localhost/user/1.gif?foo=bar&width=1024&height=768' + 'http://localhost/user/1.png?foo=bar&width=1024&height=768&quality=75' ) expect(width).toBe(1024) expect(height).toBe(768) + expect(quality).toBe(75) }) }) diff --git a/packages/web/src/components/ogImage.tsx b/packages/web/src/components/ogImage.tsx index d52c86b51329..40c8b6f3c02a 100644 --- a/packages/web/src/components/ogImage.tsx +++ b/packages/web/src/components/ogImage.tsx @@ -1,22 +1,25 @@ import { useLocation } from '@redwoodjs/router' export type OgImageUrlOptions = { - extension?: 'png' | 'jpg' | 'jpeg' | 'gif' + extension?: 'png' | 'jpg' width?: number height?: number + quality?: number } export const OGIMAGE_DEFAULTS = { extension: 'png', width: 1200, height: 630, + quality: 100, } -export const useOgImageUrl = (options?: OgImageUrlOptions) => { +export const useOgImage = (options?: OgImageUrlOptions) => { const { origin, pathname, searchParams } = useLocation() const ext = options?.extension || OGIMAGE_DEFAULTS.extension const width = options?.width const height = options?.height + const quality = options?.quality const output = [origin, `.${ext}`] // special case if we're at the root, image is available at /index.ext @@ -30,6 +33,9 @@ export const useOgImageUrl = (options?: OgImageUrlOptions) => { if (height) { searchParams.append('height', height.toString()) } + if (quality) { + searchParams.append('quality', quality.toString()) + } // only append search params if there are any, so we don't up with a trailing `?` if (searchParams.size) { @@ -40,6 +46,8 @@ export const useOgImageUrl = (options?: OgImageUrlOptions) => { url: output.join(''), width: width || OGIMAGE_DEFAULTS.width, height: height || OGIMAGE_DEFAULTS.height, + quality: quality || OGIMAGE_DEFAULTS.quality, + extension: ext, ogProps: { image: [ output.join(''),