"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createAndWriteIconsToPathAsync = createAndWriteIconsToPathAsync;
function _fsExtra() {
const data = _interopRequireDefault(require("fs-extra"));
_fsExtra = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _globby() {
const data = _interopRequireDefault(require("globby"));
_globby = function () {
return data;
};
return data;
}
function _ExponentTools() {
const data = require("./ExponentTools");
_ExponentTools = function () {
return data;
};
return data;
}
function _ImageUtils() {
const data = require("../tools/ImageUtils");
_ImageUtils = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const iconScales = {
mdpi: 1,
hdpi: 1.5,
xhdpi: 2,
xxhdpi: 3,
xxxhdpi: 4
};
async function _regexFileInResSubfoldersAsync(oldText, newText, resDirPath, folderPrefix, folderSuffix, fileName) {
return Promise.all(Object.keys(iconScales).map(async key => {
return (0, _ExponentTools().regexFileAsync)(oldText, newText, _path().default.join(resDirPath, `${folderPrefix}${key}${folderSuffix}`, fileName));
}));
}
let _hasShownResizeErrorWindowsLinux = false;
async function _resizeIconsAsync(context, resPath, prefix, mdpiSize, filename, url, isDetached) {
let baseImagePath = _path().default.join(resPath, filename);
try {
if (isDetached) {
const data = context.data;
await (0, _ExponentTools().saveImageToPathAsync)(data.projectPath, url, baseImagePath);
} else {
await (0, _ExponentTools().saveUrlToPathAsync)(url, baseImagePath);
}
} catch (e) {
throw new Error(`Failed to save icon file to disk. (${e})`);
}
await Promise.all(Object.entries(iconScales).map(async ([folderSuffix, iconScale]) => {
// adaptive icons (mdpiSize 108) must be placed in a -v26 folder
let subdirectoryName = `${prefix}${folderSuffix}${mdpiSize === 108 ? '-v26' : ''}`;
let destinationPath = _path().default.join(resPath, subdirectoryName);
await (0, _ExponentTools().spawnAsyncThrowError)('/bin/cp', [baseImagePath, filename], {
stdio: 'inherit',
cwd: destinationPath
});
try {
await (0, _ImageUtils().resizeImageAsync)(mdpiSize * iconScale, filename, destinationPath);
} catch (e) {
// Turtle should be able to resize images, so if it fails we want it to throw.
// However, `sips` does not exist on Windows or Linux machines, so we expect
// resizing images to error on these OSes and want the detach process to continue anyway.
if (isDetached) {
if (!_hasShownResizeErrorWindowsLinux) {
console.warn('Failed to resize app icons. Your full size icon will be copied to all android/app/src/main/res directories. For best quality, we recommend providing downscaled versions.');
_hasShownResizeErrorWindowsLinux = true;
}
} else {
throw new Error(`Failed to resize image: ${filename}. ${e}`);
}
} // reject non-square icons
const dims = await (0, _ImageUtils().getImageDimensionsAsync)(destinationPath, filename);
if (!dims) {
// Again, only throw this error on Turtle -- we expect that this will fail
// for some detach users but we don't want this to stop the whole process.
if (!isDetached) {
throw new Error(`Unable to read the dimensions of ${filename}`);
}
} else if (dims.width !== dims.height) {
throw new Error(`Android icons must be square, the dimensions of ${filename} are ${dims}`);
}
}));
await (0, _ExponentTools().spawnAsyncThrowError)('/bin/rm', [baseImagePath]);
}
async function createAndWriteIconsToPathAsync(context, resPath, isDetached) {
let manifest = context.config; // manifest or app.json
let iconUrl = manifest.android && manifest.android.iconUrl ? manifest.android.iconUrl : manifest.iconUrl;
let notificationIconUrl = manifest.notification ? manifest.notification.iconUrl : null;
if (isDetached) {
// manifest is actually just app.json in this case, so iconUrl fields don't exist
iconUrl = manifest.android && manifest.android.icon ? manifest.android.icon : manifest.icon;
notificationIconUrl = manifest.notification ? manifest.notification.icon : null;
}
let iconBackgroundUrl;
let iconBackgroundColor;
let iconForegroundUrl;
if (manifest.android && manifest.android.adaptiveIcon) {
iconBackgroundColor = manifest.android.adaptiveIcon.backgroundColor;
if (isDetached) {
iconForegroundUrl = manifest.android.adaptiveIcon.foregroundImage;
iconBackgroundUrl = manifest.android.adaptiveIcon.backgroundImage;
} else {
iconForegroundUrl = manifest.android.adaptiveIcon.foregroundImageUrl;
iconBackgroundUrl = manifest.android.adaptiveIcon.backgroundImageUrl;
}
}
if (iconUrl || iconForegroundUrl) {
// Android 7 and below icon
if (iconUrl) {
(await (0, _globby().default)(['**/ic_launcher.png'], {
cwd: resPath,
absolute: true
})).forEach(filePath => {
_fsExtra().default.removeSync(filePath);
});
await _resizeIconsAsync(context, resPath, 'mipmap-', 48, 'ic_launcher.png', iconUrl, isDetached);
} // Adaptive icon foreground image
if (iconForegroundUrl) {
(await (0, _globby().default)(['**/ic_foreground.png'], {
cwd: resPath,
absolute: true
})).forEach(filePath => {
_fsExtra().default.removeSync(filePath);
});
await _resizeIconsAsync(context, resPath, 'mipmap-', 108, 'ic_foreground.png', iconForegroundUrl, isDetached);
} else {
// the OS's default method of coercing normal app icons to adaptive
// makes them look quite different from using an actual adaptive icon (with xml)
// so we need to support falling back to the old version on Android 8
(await (0, _globby().default)(['**/mipmap-*-v26/*'], {
cwd: resPath,
absolute: true,
dot: true
})).forEach(filePath => {
_fsExtra().default.removeSync(filePath);
});
try {
(await (0, _globby().default)(['**/mipmap-*-v26'], {
cwd: resPath,
absolute: true
})).forEach(filePath => {
_fsExtra().default.rmdirSync(filePath);
});
} catch (e) {// we don't want the entire detach script to fail if node
// can't remove the directories for whatever reason.
// people can remove the directories themselves if they need
// so just fail silently here
}
}
} // Adaptive icon background image or color
if (iconBackgroundUrl) {
await _resizeIconsAsync(context, resPath, 'mipmap-', 108, 'ic_background.png', iconBackgroundUrl, isDetached);
await _regexFileInResSubfoldersAsync('@color/iconBackground', '@mipmap/ic_background', resPath, 'mipmap-', '-v26', 'ic_launcher.xml');
} else if (iconBackgroundColor) {
await (0, _ExponentTools().regexFileAsync)('"iconBackground">#FFFFFF', `"iconBackground">${iconBackgroundColor}`, _path().default.join(resPath, 'values', 'colors.xml'));
} // Notification icon
if (notificationIconUrl) {
(await (0, _globby().default)(['**/shell_notification_icon.png'], {
cwd: resPath,
absolute: true
})).forEach(filePath => {
_fsExtra().default.removeSync(filePath);
});
await _resizeIconsAsync(context, resPath, 'drawable-', 24, 'shell_notification_icon.png', notificationIconUrl, isDetached);
}
}
//# sourceMappingURL=../__sourcemaps__/detach/AndroidIcons.js.map