Files
lnreader/plugins/withAndroidCustomizations.js
T
Rajarshee Chatterjee 7af0911f5b feat: Add High-Resolution Android Flavor Assets
[skip ci]
2026-07-25 11:54:21 +05:30

138 lines
3.6 KiB
JavaScript

const {
withAppBuildGradle,
withDangerousMod,
} = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');
const BUILD_TYPES_MARKER = '// @generated by with-android-customizations';
const BUILD_TYPES_APPLY = `${BUILD_TYPES_MARKER}
apply from: new File(
rootDir,
"../plugins/android/android-build-types.gradle",
)
`;
const ANDROID_ASSET_VARIANTS = [
{ source: 'release', target: 'main' },
{ source: 'preview', target: 'preRelease' },
{ source: 'debug', target: 'debug' },
];
const LAUNCHER_RESOURCE_NAMES = [
'ic_launcher',
'ic_launcher_background',
'ic_launcher_foreground',
'ic_launcher_monochrome',
'ic_launcher_round',
];
const DRAWABLE_RESOURCE_NAMES = [
'notification_icon',
'splash_icon',
'splashscreen_logo',
];
const ANDROID_DENSITIES = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi', 'xxxhdpi'];
const withBuildGradleCustomizations = config =>
withAppBuildGradle(config, config => {
const { contents } = config.modResults;
if (!contents.includes(BUILD_TYPES_MARKER)) {
config.modResults.contents = `${contents.trimEnd()}
${BUILD_TYPES_APPLY}`;
}
return config;
});
const removeGeneratedIconResources = resDir => {
if (!fs.existsSync(resDir)) {
return;
}
for (const resourceDirName of fs.readdirSync(resDir)) {
const resourceDir = path.join(resDir, resourceDirName);
if (!fs.statSync(resourceDir).isDirectory()) {
continue;
}
if (resourceDirName.startsWith('mipmap-')) {
for (const resourceName of LAUNCHER_RESOURCE_NAMES) {
for (const extension of ['png', 'webp', 'xml']) {
fs.rmSync(path.join(resourceDir, `${resourceName}.${extension}`), {
force: true,
});
}
}
}
if (resourceDirName.startsWith('drawable-')) {
for (const resourceName of DRAWABLE_RESOURCE_NAMES) {
for (const extension of ['png', 'webp', 'xml']) {
fs.rmSync(path.join(resourceDir, `${resourceName}.${extension}`), {
force: true,
});
}
}
}
}
};
const installVariantSplashIcons = resDir => {
for (const density of ANDROID_DENSITIES) {
const drawableDir = path.join(resDir, `drawable-${density}`);
const sourcePath = path.join(drawableDir, 'splash_icon.png');
const splashPath = path.join(drawableDir, 'splashscreen_logo.png');
const nightDrawableDir = path.join(resDir, `drawable-night-${density}`);
const nightSplashPath = path.join(
nightDrawableDir,
'splashscreen_logo.png',
);
fs.renameSync(sourcePath, splashPath);
fs.mkdirSync(nightDrawableDir, { recursive: true });
fs.copyFileSync(splashPath, nightSplashPath);
}
};
const withAndroidVariantAssets = config =>
withDangerousMod(config, [
'android',
config => {
const { projectRoot, platformProjectRoot } = config.modRequest;
for (const variant of ANDROID_ASSET_VARIANTS) {
const sourceResDir = path.join(
projectRoot,
'assets',
'android-icons',
variant.source,
'res',
);
const targetResDir = path.join(
platformProjectRoot,
'app',
'src',
variant.target,
'res',
);
removeGeneratedIconResources(targetResDir);
fs.mkdirSync(targetResDir, { recursive: true });
fs.cpSync(sourceResDir, targetResDir, { recursive: true });
installVariantSplashIcons(targetResDir);
}
return config;
},
]);
module.exports = config => {
config = withBuildGradleCustomizations(config);
return withAndroidVariantAssets(config);
};