Skip to content

Commit

Permalink
feat: custom source image for apple dark splash screens (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
userquin committed Dec 26, 2023
1 parent 99411b7 commit 7dbc09e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
10 changes: 8 additions & 2 deletions playground/pwa-assets.config.mts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createAppleSplashScreens, defineConfig, minimal2023Preset } from '@vite-pwa/assets-generator/config'
import { readFile } from 'node:fs/promises'

export default defineConfig({
headLinkOptions: {
Expand All @@ -7,10 +8,15 @@ export default defineConfig({
preset: {
...minimal2023Preset,
appleSplashScreens: createAppleSplashScreens({
async darkImageResolver(imageName) {
return imageName === 'pwa/public/favicon.svg'
? await readFile('pwa/public/splash-dark.svg')
: undefined
},
padding: 0.3,
resizeOptions: { fit: 'contain', background: 'white' },
// to test issue #28
//darkResizeOptions: { fit: 'contain', background: 'black' },
// to test issue #28, comment the line below
darkResizeOptions: { fit: 'contain', background: 'black' },
linkMediaOptions: {
log: true,
addMediaScreen: true,
Expand Down
5 changes: 5 additions & 0 deletions playground/pwa/public/splash-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 23 additions & 2 deletions src/api/apple-icons-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,36 @@ export function resolveAppleSplashScreensInstructions(

sizesMap.clear()

// eslint-disable-next-line n/prefer-global/buffer
const cache: Record<string, Promise<Buffer>> = {}
const originalName = imageAssets.originalName!

// eslint-disable-next-line n/prefer-global/buffer
const imageResolver = (dark: boolean): Promise<Buffer> => {
if (!dark || typeof appleSplashScreens.darkImageResolver !== 'function')
return Promise.resolve(image)

const cached = cache[originalName]
if (cached)
return cached

return cache[originalName] = appleSplashScreens
.darkImageResolver(originalName)
.then(darkImage => Promise.resolve(darkImage ?? image))
}

for (const size of splashScreens) {
const name = resolveName(size.landscape, size.size, size.dark)
const url = `${imageAssets.basePath}${name}`
const promise = () => generateMaskableAsset('png', image, size.size, {
const promise = () => imageResolver(size.dark === true).then(i => generateMaskableAsset('png', i, size.size, {
padding: size.padding,
resizeOptions: {
...size.resizeOptions,
background: size.resizeOptions?.background ?? (size.dark ? 'black' : 'white'),
},
outputOptions: size.png,
})
}))

instructions.appleSplashScreen[url] = {
name,
url,
Expand Down Expand Up @@ -159,6 +178,7 @@ function resolveAppleSplashScreens(
sizes,
name = defaultSplashScreenName,
png: usePng = {},
darkImageResolver,
} = useAppleSplashScreens

// Initialize defaults
Expand Down Expand Up @@ -186,6 +206,7 @@ function resolveAppleSplashScreens(
xhtml = false,
} = useLinkMediaOptions
appleSplashScreens = {
darkImageResolver,
padding,
sizes,
linkMediaOptions: {
Expand Down
5 changes: 4 additions & 1 deletion src/api/instructions-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ export async function resolveInstructions(imageAssets: ImageAssets) {
return instructions
}

async function resolvePreset(preset: BuiltInPreset | Preset, faviconPreset?: HtmlLinkPreset): Promise<[Preset, HtmlLinkPreset]> {
async function resolvePreset(
preset: BuiltInPreset | Preset,
faviconPreset?: HtmlLinkPreset,
): Promise<[preset: Preset, htmlLinkPreset: HtmlLinkPreset]> {
if (typeof preset === 'object')
return [preset, faviconPreset ?? 'default']

Expand Down
20 changes: 20 additions & 0 deletions src/splash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ export const AllAppleDeviceNames = Array.from(Object.keys(appleSplashScreenSizes

export function createAppleSplashScreens(
options: {
/**
* The image to use for generating dark apple splash screens assets.
*
* By default, it will use the original image.
*
* @param imageName The image name configured in images.
*/
// eslint-disable-next-line n/prefer-global/buffer
darkImageResolver?: (imageName: string) => Promise<Buffer | undefined>
padding?: number
resizeOptions?: ResizeOptions
darkResizeOptions?: ResizeOptions
Expand All @@ -105,6 +114,7 @@ export function createAppleSplashScreens(
devices: AppleDeviceName[] = AllAppleDeviceNames,
) {
const {
darkImageResolver,
padding,
resizeOptions,
darkResizeOptions,
Expand All @@ -114,6 +124,7 @@ export function createAppleSplashScreens(
} = options

return {
darkImageResolver,
sizes: devices.map(deviceName => appleSplashScreenSizes[deviceName]),
padding,
resizeOptions,
Expand All @@ -127,6 +138,15 @@ export function createAppleSplashScreens(
export function combinePresetAndAppleSplashScreens(
preset: Preset,
options: {
/**
* The image to use for generating dark apple splash screens assets.
*
* By default, it will use the original image.
*
* @param imageName The image name configured in images.
*/
// eslint-disable-next-line n/prefer-global/buffer
darkImageResolver?: (imageName: string) => Promise<Buffer | undefined>
padding?: number
resizeOptions?: ResizeOptions
darkResizeOptions?: ResizeOptions
Expand Down
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export interface AppleTouchStartupImageOptions {
}

export interface AppleSplashScreens {
/**
* The image to use for generating dark apple splash screens assets.
*
* By default, it will use the original image.
*
* @param imageName The image name configured in images.
*/
// eslint-disable-next-line n/prefer-global/buffer
darkImageResolver?: (imageName: string) => Promise<Buffer | undefined>
sizes: AppleDeviceSize[]
/**
* The padding to add to the splash screen.
Expand Down Expand Up @@ -124,6 +133,8 @@ export interface AppleSplashScreens {
}

export interface ResolvedAppleSplashScreens {
// eslint-disable-next-line n/prefer-global/buffer
darkImageResolver?: (imageName: string) => Promise<Buffer | undefined>
padding: number
sizes: AppleDeviceSize[]
linkMediaOptions: Required<AppleTouchStartupImageOptions>
Expand Down

0 comments on commit 7dbc09e

Please sign in to comment.