"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