mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-20 23:56:20 +08:00
feat: add monochrome app icon support (#1550)
* Added the monochrome version for Cordova's icon * android: modified the ic_launcher.xml to include the monochrome drawable * android: replaced monochrome image with rasterized images * android: Added support for custom monochrome icons defined in config.xml * android: Updated Tests * android: wrapped inside if(monochrome) * android: Update templates/project/res/mipmap-hdpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * Update lib/prepare.js Co-authored-by: エリス <erisu@users.noreply.github.com> * android: Update templates/project/res/mipmap-ldpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * android: Update templates/project/res/mipmap-mdpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * android Update templates/project/res/mipmap-xhdpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * android: Update templates/project/res/mipmap-xxhdpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * android: Update templates/project/res/mipmap-xxxhdpi-v26/ic_launcher.xml Co-authored-by: エリス <erisu@users.noreply.github.com> * android: Update lib/prepare.js Co-authored-by: エリス <erisu@users.noreply.github.com> * Resolved lint errors * fix: test failure --------- Co-authored-by: エリス <erisu@users.noreply.github.com>
This commit is contained in:
parent
a78fad1783
commit
016018513e
@ -703,8 +703,10 @@ function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
@ -728,17 +730,23 @@ function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformReso
|
||||
// project's config.xml location, so we use it as base path.
|
||||
let background;
|
||||
let foreground;
|
||||
let monochrome;
|
||||
let targetPathBackground;
|
||||
let targetPathForeground;
|
||||
let targetPathMonochrome;
|
||||
|
||||
for (const density in android_icons) {
|
||||
let backgroundVal = '@mipmap/ic_launcher_background';
|
||||
let foregroundVal = '@mipmap/ic_launcher_foreground';
|
||||
const monochromeVal = '@mipmap/ic_launcher_monochrome';
|
||||
|
||||
background = android_icons[density].background;
|
||||
foreground = android_icons[density].foreground;
|
||||
monochrome = android_icons[density].monochrome;
|
||||
|
||||
if (!background || !foreground) {
|
||||
const isAdaptiveIcon = background && foreground;
|
||||
const isMonochromeIcon = monochrome && isAdaptiveIcon;
|
||||
if (!isMonochromeIcon || !isAdaptiveIcon) {
|
||||
// This icon isn't an adaptive icon, so skip it
|
||||
continue;
|
||||
}
|
||||
@ -769,12 +777,34 @@ function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformReso
|
||||
resourceMap[targetPathForeground] = android_icons[density].foreground;
|
||||
}
|
||||
|
||||
if (monochrome) {
|
||||
if (path.extname(path.basename(monochrome)) === '.xml') {
|
||||
// Vector Use Case
|
||||
targetPathMonochrome = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_monochrome.xml', path.basename(android_icons[density].monochrome));
|
||||
resourceMap[targetPathMonochrome] = android_icons[density].monochrome;
|
||||
} else if (path.extname(path.basename(monochrome)) === '.png') {
|
||||
// Images Use Case
|
||||
targetPathMonochrome = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_monochrome.png', path.basename(android_icons[density].monochrome));
|
||||
resourceMap[targetPathMonochrome] = android_icons[density].monochrome;
|
||||
}
|
||||
}
|
||||
|
||||
// create an XML for DPI and set color
|
||||
const icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||
let icLauncherTemplate = '';
|
||||
if (monochrome) {
|
||||
icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="` + backgroundVal + `" />
|
||||
<foreground android:drawable="` + foregroundVal + `" />
|
||||
<monochrome android:drawable="` + monochromeVal + `" />
|
||||
</adaptive-icon>`;
|
||||
} else {
|
||||
icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="` + backgroundVal + `" />
|
||||
<foreground android:drawable="` + foregroundVal + `" />
|
||||
</adaptive-icon>`;
|
||||
}
|
||||
|
||||
const launcherXmlPath = path.join(platformResourcesDir, 'mipmap-' + density + '-v26', 'ic_launcher.xml');
|
||||
|
||||
@ -788,6 +818,7 @@ function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformReso
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
let defaultTargetPathBackground;
|
||||
let defaultTargetPathForeground;
|
||||
let defaultTargetPathMonochrome;
|
||||
|
||||
if (background.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
@ -814,6 +845,18 @@ function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformReso
|
||||
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.png', path.basename(default_icon.foreground));
|
||||
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
|
||||
}
|
||||
|
||||
if (monochrome) {
|
||||
if (path.extname(path.basename(monochrome)) === '.xml') {
|
||||
// Vector Use Case
|
||||
defaultTargetPathMonochrome = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_monochrome.xml', path.basename(default_icon.monochrome));
|
||||
resourceMap[defaultTargetPathMonochrome] = default_icon.monochrome;
|
||||
} else if (path.extname(path.basename(monochrome)) === '.png') {
|
||||
// Images Use Case
|
||||
defaultTargetPathMonochrome = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_monochrome.png', path.basename(default_icon.monochrome));
|
||||
resourceMap[defaultTargetPathMonochrome] = default_icon.monochrome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resourceMap;
|
||||
@ -884,6 +927,11 @@ function prepareIcons (icons) {
|
||||
const favor = {};
|
||||
|
||||
// populating found icon.
|
||||
if (icon.background && icon.foreground && icon.monochrome) {
|
||||
found.background = icon.background;
|
||||
found.foreground = icon.foreground;
|
||||
found.monochrome = icon.monochrome;
|
||||
}
|
||||
if (icon.background && icon.foreground) {
|
||||
found.background = icon.background;
|
||||
found.foreground = icon.foreground;
|
||||
@ -892,6 +940,11 @@ function prepareIcons (icons) {
|
||||
found.src = icon.src;
|
||||
}
|
||||
|
||||
if (default_icon.background && default_icon.foreground && default_icon.monochrome) {
|
||||
favor.background = default_icon.background;
|
||||
favor.foreground = default_icon.foreground;
|
||||
favor.monochrome = default_icon.monochrome;
|
||||
}
|
||||
if (default_icon.background && default_icon.foreground) {
|
||||
favor.background = default_icon.background;
|
||||
favor.foreground = default_icon.foreground;
|
||||
@ -929,8 +982,10 @@ function cleanIcons (projectRoot, projectConfig, platformResourcesDir) {
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
|
@ -51,8 +51,10 @@ function createResourceMap (target) {
|
||||
if (!target || target === 'ic_launcher.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher.png')] = null;
|
||||
if (!target || target === 'ic_launcher_foreground.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_foreground.png')] = null;
|
||||
if (!target || target === 'ic_launcher_background.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_background.png')] = null;
|
||||
if (!target || target === 'ic_launcher_background.png') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_monochrome.png')] = null;
|
||||
if (!target || target === 'ic_launcher_foreground.xml') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_foreground.xml')] = null;
|
||||
if (!target || target === 'ic_launcher_background.xml') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_background.xml')] = null;
|
||||
if (!target || target === 'ic_launcher_background.xml') resources[path.join(PATH_RESOURCE, mipmap, 'ic_launcher_monochrome.xml')] = null;
|
||||
|
||||
if (
|
||||
!mipmap.includes('-v26') &&
|
||||
@ -136,10 +138,14 @@ describe('prepare', () => {
|
||||
return createResourceMap('ic_launcher_foreground.png');
|
||||
} else if (resourceName.includes('ic_launcher_background.png')) {
|
||||
return createResourceMap('ic_launcher_background.png');
|
||||
} else if (resourceName.includes('ic_launcher_monochrome.png')) {
|
||||
return createResourceMap('ic_launcher_monochrome.png');
|
||||
} else if (resourceName.includes('ic_launcher_foreground.xml')) {
|
||||
return createResourceMap('ic_launcher_foreground.xml');
|
||||
} else if (resourceName.includes('ic_launcher_background.xml')) {
|
||||
return createResourceMap('ic_launcher_background.xml');
|
||||
} else if (resourceName.includes('ic_launcher_monochrome.xml')) {
|
||||
return createResourceMap('ic_launcher_monochrome.xml');
|
||||
} else if (resourceName.includes('ic_launcher.xml')) {
|
||||
return createResourceMap('ic_launcher.xml');
|
||||
}
|
||||
@ -305,7 +311,9 @@ describe('prepare', () => {
|
||||
return [mockGetIconItem({
|
||||
density: 'mdpi',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.xml'
|
||||
foreground: 'res/icon/android/mdpi-foreground.xml',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
|
||||
})];
|
||||
};
|
||||
|
||||
@ -343,7 +351,8 @@ describe('prepare', () => {
|
||||
return [mockGetIconItem({
|
||||
density: 'mdpi',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.png'
|
||||
foreground: 'res/icon/android/mdpi-foreground.png',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
})];
|
||||
};
|
||||
|
||||
@ -352,6 +361,7 @@ describe('prepare', () => {
|
||||
const phaseOneModification = {};
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png';
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png';
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_monochrome.png')] = 'res/icon/android/mdpi-monochrome.png';
|
||||
const phaseOneUpdatedIconsForAdaptive = Object.assign({}, resourceMap, phaseOneModification);
|
||||
|
||||
updateIconResourceForAdaptiveSpy = jasmine.createSpy('updateIconResourceForAdaptiveSpy');
|
||||
@ -363,6 +373,7 @@ describe('prepare', () => {
|
||||
const phaseTwoModification = {};
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-foreground.png';
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png';
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_monochrome.png')] = 'res/icon/android/mdpi-monochrome.png';
|
||||
const phaseTwoUpdatedIconsForLegacy = Object.assign({}, phaseOneUpdatedIconsForAdaptive, phaseTwoModification);
|
||||
|
||||
updateIconResourceForLegacySpy = jasmine.createSpy('updateIconResourceForLegacySpy');
|
||||
@ -400,7 +411,8 @@ describe('prepare', () => {
|
||||
density: 'mdpi',
|
||||
src: 'res/icon/android/mdpi-icon.png',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.png'
|
||||
foreground: 'res/icon/android/mdpi-foreground.png',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
})];
|
||||
};
|
||||
|
||||
@ -409,6 +421,7 @@ describe('prepare', () => {
|
||||
const phaseOneModification = {};
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png';
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png';
|
||||
phaseOneModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_monochrome.png')] = 'res/icon/android/mdpi-monochrome.png';
|
||||
const phaseOneUpdatedIconsForAdaptive = Object.assign({}, resourceMap, phaseOneModification);
|
||||
|
||||
updateIconResourceForAdaptiveSpy = jasmine.createSpy('updateIconResourceForAdaptiveSpy');
|
||||
@ -420,6 +433,7 @@ describe('prepare', () => {
|
||||
const phaseTwoModification = {};
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi', 'ic_launcher.png')] = 'res/icon/android/mdpi-foreground.png';
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png';
|
||||
phaseTwoModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_monochrome.png')] = 'res/icon/android/mdpi-monochrome.png';
|
||||
const phaseTwoUpdatedIconsForLegacy = Object.assign({}, phaseOneUpdatedIconsForAdaptive, phaseTwoModification);
|
||||
|
||||
updateIconResourceForLegacySpy = jasmine.createSpy('updateIconResourceForLegacySpy');
|
||||
@ -511,13 +525,15 @@ describe('prepare', () => {
|
||||
const ldpi = mockGetIconItem({
|
||||
density: 'ldpi',
|
||||
background: 'res/icon/android/ldpi-background.png',
|
||||
foreground: 'res/icon/android/ldpi-foreground.png'
|
||||
foreground: 'res/icon/android/ldpi-foreground.png',
|
||||
monochrome: 'res/icon/android/ldpi-monochrome.png'
|
||||
});
|
||||
|
||||
const mdpi = mockGetIconItem({
|
||||
density: 'mdpi',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.png'
|
||||
foreground: 'res/icon/android/mdpi-foreground.png',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
});
|
||||
|
||||
const icons = [ldpi, mdpi];
|
||||
@ -614,7 +630,8 @@ describe('prepare', () => {
|
||||
mdpi: mockGetIconItem({
|
||||
density: 'mdpi',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.png'
|
||||
foreground: 'res/icon/android/mdpi-foreground.png',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
})
|
||||
},
|
||||
default_icon: undefined
|
||||
@ -636,6 +653,7 @@ describe('prepare', () => {
|
||||
const expectedModification = {};
|
||||
expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_background.png')] = 'res/icon/android/mdpi-background.png';
|
||||
expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_foreground.png')] = 'res/icon/android/mdpi-foreground.png';
|
||||
expectedModification[path.join(PATH_RESOURCE, 'mipmap-mdpi-v26', 'ic_launcher_monochrome.png')] = 'res/icon/android/mdpi-monochrome.png';
|
||||
|
||||
const expected = Object.assign({}, resourceMap, expectedModification);
|
||||
const actual = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);
|
||||
@ -668,7 +686,8 @@ describe('prepare', () => {
|
||||
const icons = [mockGetIconItem({
|
||||
density: 'mdpi',
|
||||
background: 'res/icon/android/mdpi-background.png',
|
||||
foreground: 'res/icon/android/mdpi-foreground.png'
|
||||
foreground: 'res/icon/android/mdpi-foreground.png',
|
||||
monochrome: 'res/icon/android/mdpi-monochrome.png'
|
||||
})];
|
||||
const projectRoot = '/mock';
|
||||
const projectConfig = {
|
||||
|
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
BIN
templates/project/res/mipmap-hdpi-v26/ic_launcher_monochrome.png
Normal file
BIN
templates/project/res/mipmap-hdpi-v26/ic_launcher_monochrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
BIN
templates/project/res/mipmap-mdpi-v26/ic_launcher_monochrome.png
Normal file
BIN
templates/project/res/mipmap-mdpi-v26/ic_launcher_monochrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 916 B |
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
Loading…
Reference in New Issue
Block a user