Skip to content

Commit

Permalink
Fix for the [issue 622](#622) dark mode support for android
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel committed Dec 13, 2024
1 parent 5555191 commit 6dc7b90
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const enum AssetKind {
Logo = 'logo',
LogoDark = 'logo-dark',
AdaptiveIcon = 'adaptive-icon',
AdaptiveIconDark = 'adaptive-icon-dark',
Icon = 'icon',
IconForeground = 'icon-foreground',
IconBackground = 'icon-background',
Expand Down
55 changes: 55 additions & 0 deletions src/platforms/android/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,61 @@ export const ANDROID_XXXHDPI_ADAPTIVE_ICON: AndroidOutputAssetTemplateAdaptiveIc
density: AndroidDensity.Xxxhdpi,
};

// Dark/night mode adaptive icons
export const ANDROID_LDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 81,
height: 81,
density: AndroidDensity.LdpiNight,
};

export const ANDROID_MDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 108,
height: 108,
density: AndroidDensity.MdpiNight,
};

export const ANDROID_HDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 162,
height: 162,
density: AndroidDensity.HdpiNight,
};

export const ANDROID_XHDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 216,
height: 216,
density: AndroidDensity.XhdpiNight,
};

export const ANDROID_XXHDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 324,
height: 324,
density: AndroidDensity.XxhdpiNight,
};

export const ANDROID_XXXHDPI_ADAPTIVE_ICON_DARK: AndroidOutputAssetTemplateAdaptiveIcon = {
platform: Platform.Android,
kind: AssetKind.AdaptiveIconDark,
format: Format.Png,
width: 432,
height: 432,
density: AndroidDensity.XxxhdpiNight,
};

//
// Splash screens
//
Expand Down
37 changes: 17 additions & 20 deletions src/platforms/android/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { mkdirp, pathExists, writeFile } from '@ionic/utils-fs';
import { dirname, join, relative } from 'path';
import type { OutputInfo, Sharp } from 'sharp';
import {mkdirp, pathExists, writeFile} from '@ionic/utils-fs';
import {dirname, join, relative} from 'path';
import type {OutputInfo, Sharp} from 'sharp';
import sharp from 'sharp';

import type { AssetGeneratorOptions } from '../../asset-generator';
import { AssetGenerator } from '../../asset-generator';
import type {AssetGeneratorOptions} from '../../asset-generator';
import {AssetGenerator} from '../../asset-generator';
import type {
AndroidOutputAssetTemplate,
AndroidOutputAssetTemplateAdaptiveIcon,
AndroidOutputAssetTemplateSplash,
} from '../../definitions';
import { AssetKind, Platform } from '../../definitions';
import { BadPipelineError, BadProjectError } from '../../error';
import type { InputAsset } from '../../input-asset';
import { OutputAsset } from '../../output-asset';
import type { Project } from '../../project';
import { warn } from '../../util/log';
import {AssetKind, Platform} from '../../definitions';
import {BadPipelineError, BadProjectError} from '../../error';
import type {InputAsset} from '../../input-asset';
import {OutputAsset} from '../../output-asset';
import type {Project} from '../../project';
import {warn} from '../../util/log';

import * as AndroidAssetTemplates from './assets';

Expand Down Expand Up @@ -118,11 +118,7 @@ export class AndroidAssetGenerator extends AssetGenerator {
asset: InputAsset,
pipe: Sharp,
): Promise<OutputAsset[]> {
// Current versions of Android don't appear to support night mode icons (13+ might?)
// so, for now, we only generate light mode ones
if (asset.kind === AssetKind.LogoDark) {
return [];
}
const isNightMode = asset.kind !== AssetKind.Logo;

// Create the background pipeline for the generated icons
const backgroundPipe = sharp({
Expand All @@ -131,14 +127,15 @@ export class AndroidAssetGenerator extends AssetGenerator {
height: asset.height!,
channels: 4,
background:
asset.kind === AssetKind.Logo
? this.options.iconBackgroundColor ?? '#ffffff'
: this.options.iconBackgroundColorDark ?? '#111111',
isNightMode
? this.options.iconBackgroundColorDark ?? '#111111'
: this.options.iconBackgroundColor ?? '#ffffff',
},
});

const adaptiveIconKind = isNightMode ? AssetKind.AdaptiveIconDark : AssetKind.AdaptiveIcon;
const icons = Object.values(AndroidAssetTemplates).filter(
(a) => a.kind === AssetKind.AdaptiveIcon,
(a) => a.kind === adaptiveIconKind,
) as AndroidOutputAssetTemplateAdaptiveIcon[];

const backgroundImages = await Promise.all(
Expand Down
6 changes: 2 additions & 4 deletions test/platforms/android.asset.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { copy, pathExists, readdirp, readFile, rmSync as rm, statSync } from '@ionic/utils-fs';
import { copy, pathExists, rmSync as rm } from '@ionic/utils-fs';
import tempy from 'tempy';
import sharp from 'sharp';
import { join } from 'path';
Expand All @@ -7,12 +7,10 @@ import { Context, loadContext } from '../../src/ctx';
import {
AndroidOutputAssetTemplate,
AndroidOutputAssetTemplateAdaptiveIcon,
AssetKind,
Assets,
} from '../../src/definitions';
import { OutputAsset } from '../../src/output-asset';
import { AndroidAssetGenerator } from '../../src/platforms/android';
import * as AndroidAssets from '../../src/platforms/android/assets';

describe('Android asset test', () => {
let ctx: Context;
Expand Down Expand Up @@ -187,7 +185,7 @@ describe('Android Asset Test - Logo Only', () => {
let generatedAssets = ((await assets.logoDark?.generate(strategy, ctx.project)) ??
[]) as OutputAsset<AndroidOutputAssetTemplate>[];

expect(generatedAssets.length).toBe(13);
expect(generatedAssets.length).toBe(25);
await verifySizes(generatedAssets);
});

Expand Down

0 comments on commit 6dc7b90

Please sign in to comment.