1"use strict"; 2var __importDefault = (this && this.__importDefault) || function (mod) { 3 return (mod && mod.__esModule) ? mod : { "default": mod }; 4}; 5Object.defineProperty(exports, "__esModule", { value: true }); 6exports.withNotificationsAndroid = exports.setNotificationIconColorAsync = exports.setNotificationConfigAsync = exports.setNotificationIconAsync = exports.getNotificationColor = exports.getNotificationIcon = exports.withNotificationManifest = exports.withNotificationIconColor = exports.withNotificationIcons = exports.NOTIFICATION_ICON_COLOR_RESOURCE = exports.NOTIFICATION_ICON_COLOR = exports.NOTIFICATION_ICON_RESOURCE = exports.NOTIFICATION_ICON = exports.META_DATA_NOTIFICATION_ICON_COLOR = exports.META_DATA_NOTIFICATION_ICON = void 0; 7const config_plugins_1 = require("@expo/config-plugins"); 8const Resources_1 = require("@expo/config-plugins/build/android/Resources"); 9const android_plugins_1 = require("@expo/config-plugins/build/plugins/android-plugins"); 10const XML_1 = require("@expo/config-plugins/build/utils/XML"); 11const image_utils_1 = require("@expo/image-utils"); 12const fs_extra_1 = __importDefault(require("fs-extra")); 13const path_1 = __importDefault(require("path")); 14const { Colors } = config_plugins_1.AndroidConfig; 15const { ANDROID_RES_PATH, dpiValues } = config_plugins_1.AndroidConfig.Icon; 16const { addMetaDataItemToMainApplication, getMainApplicationOrThrow, removeMetaDataItemFromMainApplication, } = config_plugins_1.AndroidConfig.Manifest; 17const BASELINE_PIXEL_SIZE = 24; 18exports.META_DATA_NOTIFICATION_ICON = 'expo.modules.notifications.default_notification_icon'; 19exports.META_DATA_NOTIFICATION_ICON_COLOR = 'expo.modules.notifications.default_notification_color'; 20exports.NOTIFICATION_ICON = 'notification_icon'; 21exports.NOTIFICATION_ICON_RESOURCE = `@drawable/${exports.NOTIFICATION_ICON}`; 22exports.NOTIFICATION_ICON_COLOR = 'notification_icon_color'; 23exports.NOTIFICATION_ICON_COLOR_RESOURCE = `@color/${exports.NOTIFICATION_ICON_COLOR}`; 24exports.withNotificationIcons = config => { 25 return config_plugins_1.withDangerousMod(config, [ 26 'android', 27 async (config) => { 28 await setNotificationIconAsync(config, config.modRequest.projectRoot); 29 return config; 30 }, 31 ]); 32}; 33exports.withNotificationIconColor = config => { 34 return config_plugins_1.withDangerousMod(config, [ 35 'android', 36 async (config) => { 37 await setNotificationIconColorAsync(config, config.modRequest.projectRoot); 38 return config; 39 }, 40 ]); 41}; 42exports.withNotificationManifest = android_plugins_1.createAndroidManifestPlugin(setNotificationConfigAsync, 'withNotificationManifest'); 43function getNotificationIcon(config) { 44 var _a; 45 return ((_a = config.notification) === null || _a === void 0 ? void 0 : _a.icon) || null; 46} 47exports.getNotificationIcon = getNotificationIcon; 48function getNotificationColor(config) { 49 var _a; 50 return ((_a = config.notification) === null || _a === void 0 ? void 0 : _a.color) || null; 51} 52exports.getNotificationColor = getNotificationColor; 53/** 54 * Applies configuration for expo-notifications, including 55 * the notification icon and notification color. 56 */ 57async function setNotificationIconAsync(config, projectRoot) { 58 const icon = getNotificationIcon(config); 59 if (icon) { 60 await writeNotificationIconImageFilesAsync(icon, projectRoot); 61 } 62 else { 63 await removeNotificationIconImageFilesAsync(projectRoot); 64 } 65} 66exports.setNotificationIconAsync = setNotificationIconAsync; 67async function setNotificationConfigAsync(config, manifest) { 68 const icon = getNotificationIcon(config); 69 const color = getNotificationColor(config); 70 const mainApplication = getMainApplicationOrThrow(manifest); 71 if (icon) { 72 addMetaDataItemToMainApplication(mainApplication, exports.META_DATA_NOTIFICATION_ICON, exports.NOTIFICATION_ICON_RESOURCE, 'resource'); 73 } 74 else { 75 removeMetaDataItemFromMainApplication(mainApplication, exports.META_DATA_NOTIFICATION_ICON); 76 } 77 if (color) { 78 addMetaDataItemToMainApplication(mainApplication, exports.META_DATA_NOTIFICATION_ICON_COLOR, exports.NOTIFICATION_ICON_COLOR_RESOURCE, 'resource'); 79 } 80 else { 81 removeMetaDataItemFromMainApplication(mainApplication, exports.META_DATA_NOTIFICATION_ICON_COLOR); 82 } 83 return manifest; 84} 85exports.setNotificationConfigAsync = setNotificationConfigAsync; 86async function setNotificationIconColorAsync(config, projectRoot) { 87 const color = getNotificationColor(config); 88 const colorsXmlPath = await Colors.getProjectColorsXMLPathAsync(projectRoot); 89 let colorsJson = await Resources_1.readResourcesXMLAsync({ path: colorsXmlPath }); 90 if (color) { 91 const colorItemToAdd = Resources_1.buildResourceItem({ name: exports.NOTIFICATION_ICON_COLOR, value: color }); 92 colorsJson = Colors.setColorItem(colorItemToAdd, colorsJson); 93 } 94 else { 95 colorsJson = Colors.removeColorItem(exports.NOTIFICATION_ICON_COLOR, colorsJson); 96 } 97 await XML_1.writeXMLAsync({ path: colorsXmlPath, xml: colorsJson }); 98} 99exports.setNotificationIconColorAsync = setNotificationIconColorAsync; 100async function writeNotificationIconImageFilesAsync(icon, projectRoot) { 101 await Promise.all(Object.values(dpiValues).map(async ({ folderName, scale }) => { 102 const drawableFolderName = folderName.replace('mipmap', 'drawable'); 103 const dpiFolderPath = path_1.default.resolve(projectRoot, ANDROID_RES_PATH, drawableFolderName); 104 await fs_extra_1.default.ensureDir(dpiFolderPath); 105 const iconSizePx = BASELINE_PIXEL_SIZE * scale; 106 try { 107 const resizedIcon = (await image_utils_1.generateImageAsync({ projectRoot, cacheType: 'android-notification' }, { 108 src: icon, 109 width: iconSizePx, 110 height: iconSizePx, 111 resizeMode: 'cover', 112 backgroundColor: 'transparent', 113 })).source; 114 await fs_extra_1.default.writeFile(path_1.default.resolve(dpiFolderPath, exports.NOTIFICATION_ICON + '.png'), resizedIcon); 115 } 116 catch (e) { 117 throw new Error('Encountered an issue resizing Android notification icon: ' + e); 118 } 119 })); 120} 121async function removeNotificationIconImageFilesAsync(projectRoot) { 122 await Promise.all(Object.values(dpiValues).map(async ({ folderName }) => { 123 const drawableFolderName = folderName.replace('mipmap', 'drawable'); 124 const dpiFolderPath = path_1.default.resolve(projectRoot, ANDROID_RES_PATH, drawableFolderName); 125 await fs_extra_1.default.remove(path_1.default.resolve(dpiFolderPath, exports.NOTIFICATION_ICON + '.png')); 126 })); 127} 128exports.withNotificationsAndroid = config => { 129 config = exports.withNotificationIconColor(config); 130 config = exports.withNotificationIcons(config); 131 config = exports.withNotificationManifest(config); 132 return config; 133}; 134