Skip to content

Issue 55/separate maskable icon file #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@ plugins:[
statusBarStyle: 'default',
themeColor: '#666600',
backgroundColor: '#ffffff',

// icon should be a path to the static folder i.e. 'static/icon.png'
icon: '',

// set {maskableIcon: true} to use the same icon (this will set
// {purpose: 'maskable any'}), or specify a different icon path
maskableIcon: true, // Optional
shortName: 'Gridsome', // Optional
description: 'Gridsome is awesome!',// Optional
categories: ['education'], // Optional
lang: 'en-GB', // Optional
dir: 'auto', // Optional
maskableIcon: true, // Optional
screenshots: [ // Optional
{
src: 'src/screenshot1.png',
Expand Down
46 changes: 36 additions & 10 deletions src/files/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const createManifest = async (context, config, queue, options) => {
const manifestDest = path.join(config.outputDir, options.manifestPath);
const iconsDir = path.join(config.outputDir, options.staticAssetsDir);
const iconName = options.icon.split('/').slice(-1)[0];
let maskableIconName = typeof options.maskableIcon === 'string'
? options.maskableIcon.split('/').slice(-1)[0]
: null

// Generate all size images from options.icon
const sizes = [512, 384, 192, 180, 152, 144, 128, 120, 96, 72, 48, 16];
Expand All @@ -15,16 +18,39 @@ export const createManifest = async (context, config, queue, options) => {
const icons = [];
await Promise.all(sizes.map((size) => {
const sizes = `${size}x${size}`;
const imagePath = path.join(iconsDir, rename(iconName, { suffix: `-${sizes}` }))
const src = path.relative(config.outputDir, imagePath);
const type = 'image/' + iconName.split('.').slice(-1)[0];
icons.push({
src,
type,
sizes,
purpose: options.maskableIcon ? 'maskable any' : 'any',
});
return sharp(options.icon).resize(size, size).toFile(imagePath);

// for { icon }
let imagePath = path.join(iconsDir, rename(iconName, { suffix: `-${sizes}` }))
let src = path.relative(config.outputDir, imagePath);
let type = 'image/' + iconName.split('.').slice(-1)[0];
let purpose = 'any'

// maskableIcon can now be boolean or an icon path.
// if it is true, or is the same icon file as standard icon, set 'maskable any'
// also revert maskableIconName to null, as we won't need to process separately
if (options.maskableIcon === true || options.maskableIcon === options.icon) {
purpose = 'maskable any'
maskableIconName = null
}

// add and process { icon }
icons.push({src, type, sizes, purpose});
const results = [sharp(options.icon).resize(size, size).toFile(imagePath)]

// if maskableIcon is a string, then we need to process it as a separate maskable icon
if (maskableIconName) {
imagePath = path.join(iconsDir, rename(maskableIconName, { suffix: `-maskable-${sizes}` }))
src = path.relative(config.outputDir, imagePath);
type = 'image/' + maskableIconName.split('.').slice(-1)[0];
purpose = 'maskable'

// add and process { maskableIcon }
icons.push({src, type, sizes, purpose});
results.push(sharp(options.maskableIcon).resize(size, size).toFile(imagePath))
}

// always return a single promise
return Promise.all(results)
}));

await fs.outputFile(manifestDest, JSON.stringify({
Expand Down