Skip to content

Commit c8e4f4f

Browse files
committed
Improve icon processing to allow maskableIcon to specify a unique icon file
1 parent 0d74753 commit c8e4f4f

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ plugins:[
4242
statusBarStyle: 'default',
4343
themeColor: '#666600',
4444
backgroundColor: '#ffffff',
45+
46+
// icon should be a path to the static folder i.e. '/static/icon.png'
4547
icon: '',
48+
49+
// set {maskableIcon: true} to use the same icon (this will set
50+
// {purpose: 'maskable any'}), or specify a different icon path
51+
maskableIcon: true, // Optional
4652
shortName: 'Gridsome', // Optional
4753
description: 'Gridsome is awesome!',// Optional
4854
categories: ['education'], // Optional
4955
lang: 'en-GB', // Optional
5056
dir: 'auto', // Optional
51-
maskableIcon: true, // Optional
5257
screenshots: [ // Optional
5358
{
5459
src: 'src/screenshot1.png',

src/files/manifest.js

+34-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ export const createManifest = async (context, config, queue, options) => {
77
const manifestDest = path.join(config.outputDir, options.manifestPath);
88
const iconsDir = path.join(config.outputDir, options.staticAssetsDir);
99
const iconName = options.icon.split('/').slice(-1)[0];
10+
const maskableIconName = typeof options.maskableIcon === 'string'
11+
? options.maskableIcon.split('/').slice(-1)[0]
12+
: null
1013

1114
// Generate all size images from options.icon
1215
const sizes = [512, 384, 192, 180, 152, 144, 128, 120, 96, 72, 48, 16];
@@ -15,16 +18,37 @@ export const createManifest = async (context, config, queue, options) => {
1518
const icons = [];
1619
await Promise.all(sizes.map((size) => {
1720
const sizes = `${size}x${size}`;
18-
const imagePath = path.join(iconsDir, rename(iconName, { suffix: `-${sizes}` }))
19-
const src = path.relative(config.outputDir, imagePath);
20-
const type = 'image/' + iconName.split('.').slice(-1)[0];
21-
icons.push({
22-
src,
23-
type,
24-
sizes,
25-
purpose: options.maskableIcon ? 'maskable any' : 'any',
26-
});
27-
return sharp(options.icon).resize(size, size).toFile(imagePath);
21+
22+
// for { icon }
23+
let imagePath = path.join(iconsDir, rename(iconName, { suffix: `-${sizes}` }))
24+
let src = path.relative(config.outputDir, imagePath);
25+
let type = 'image/' + iconName.split('.').slice(-1)[0];
26+
let purpose = 'any'
27+
28+
// maskableIcon can now be boolean or an icon path.
29+
// if it is true, or is the same icon file as standard icon, set 'maskable any'
30+
if (options.maskableIcon === true || options.maskableIcon === options.icon) {
31+
purpose = 'maskable any'
32+
}
33+
34+
// add and process { icon }
35+
icons.push({src, type, sizes, purpose });
36+
const results = [sharp(options.icon).resize(size, size).toFile(imagePath)]
37+
38+
// if maskableIcon is a string, then we need to process it as a separate maskable icon
39+
if (options.maskableIcon && typeof options.maskableIcon === 'string') {
40+
imagePath = path.join(iconsDir, rename(maskableIconName, { suffix: `-maskable-${sizes}` }))
41+
src = path.relative(config.outputDir, imagePath);
42+
type = 'image/' + iconName.split('.').slice(-1)[0];
43+
purpose = 'maskable'
44+
45+
// add and process { maskableIcon }
46+
icons.push({src, type, sizes, purpose });
47+
results.push(sharp(options.maskableIconName).resize(size, size).toFile(imagePath))
48+
}
49+
50+
// always return a single promise
51+
return Promise.all(results)
2852
}));
2953

3054
await fs.outputFile(manifestDest, JSON.stringify({

0 commit comments

Comments
 (0)