diff --git a/android/app/src/main/res-launcher/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res-launcher/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 000000000..1ef13112f --- /dev/null +++ b/android/app/src/main/res-launcher/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/android/app/src/main/res-launcher/drawable/ic_launcher_background.xml b/android/app/src/main/res-launcher/drawable/ic_launcher_background.xml new file mode 100644 index 000000000..ca3826a46 --- /dev/null +++ b/android/app/src/main/res-launcher/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher.xml similarity index 94% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher.xml index 6b78462d6..d378acd7a 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 94% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher_round.xml index 6b78462d6..d378acd7a 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/main/res-launcher/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + diff --git a/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..06c2ae637 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..0cf22d879 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..3caf60918 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..6295d899e Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..4b37dff4f Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..07249dac2 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..c1b77f576 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..926924d8a Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..9261b54e8 Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..1e239a77f Binary files /dev/null and b/android/app/src/main/res-launcher/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb2906..000000000 --- a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9bf..000000000 --- a/android/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 898f3ed59..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index dffca3601..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 64ba76f75..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index dae5e0823..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index e5ed46597..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 14ed0af35..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b0907cac3..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d8ae03154..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 2c18de9e6..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index beed3cdd2..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/ios/ReactTestApp.xcodeproj/project.pbxproj b/ios/ReactTestApp.xcodeproj/project.pbxproj index 7a03b0a44..960ad86ca 100644 --- a/ios/ReactTestApp.xcodeproj/project.pbxproj +++ b/ios/ReactTestApp.xcodeproj/project.pbxproj @@ -67,7 +67,7 @@ 19ECD0D5232ED425003D8557 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 19ECD0D7232ED425003D8557 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 19ECD0D9232ED425003D8557 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 19ECD0DB232ED427003D8557 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 19ECD0DB232ED427003D8557 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = SOURCE_ROOT; }; 19ECD0E1232ED427003D8557 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 19ECD0E3232ED427003D8557 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 19ECD0E8232ED427003D8557 /* ReactTestAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactTestAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/ios/test_app.rb b/ios/test_app.rb index 8805103ae..076b9aeb3 100644 --- a/ios/test_app.rb +++ b/ios/test_app.rb @@ -74,6 +74,48 @@ def react_native_path(project_root, target_platform) Pathname.new(resolve_module(react_native)) end +def generate_assets_catalog!(project_root, target_platform, destination) + xcassets_src = project_path('ReactTestApp/Assets.xcassets', target_platform) + xcassets_dst = File.join(destination, File.basename(xcassets_src)) + FileUtils.rm_rf(xcassets_dst) + FileUtils.cp_r(xcassets_src, destination) + + icons = platform_config('icons', project_root, target_platform) + return if icons.nil? || icons['primaryIcon'].nil? + + template = JSON.parse(File.read(File.join(xcassets_src, 'AppIcon.appiconset', 'Contents.json'))) + app_manifest_dir = File.dirname(find_file('app.json', project_root)) + + app_icons = (icons['alternateIcons'] || {}).merge({ 'AppIcon' => icons['primaryIcon'] }) + app_icons.each do |icon_set_name, app_icon| + app_icon_set = File.join(xcassets_dst, "#{icon_set_name}.appiconset") + FileUtils.mkdir_p(app_icon_set) + + icon = File.join(app_manifest_dir, app_icon['filename']) + extname = File.extname(icon) + basename = File.basename(icon, extname) + + images = [] + + template['images'].each do |image| + scale, size = image.values_at('scale', 'size') + width, height = size.split('x') + filename = "#{basename}-#{height}@#{scale}#{extname}" + images << { 'filename' => filename }.merge(image) + fork do + output = File.join(app_icon_set, filename) + scale = scale.split('x')[0].to_f + height = height.to_f * scale + width = width.to_f * scale + `sips --resampleHeightWidth #{height} #{width} --out "#{output}" "#{icon}"` + end + end + + File.write(File.join(app_icon_set, 'Contents.json'), + JSON.pretty_generate({ 'images' => images, 'info' => template['info'] })) + end +end + def react_native_pods(version) v = version.release if v == Gem::Version.new('0.0.0') || v >= Gem::Version.new('0.70') @@ -184,6 +226,8 @@ def make_project!(xcodeproj, project_root, target_platform, options) FileUtils.ln_sf(source, shared_path) unless File.exist?(shared_path) end + generate_assets_catalog!(project_root, target_platform, destination) + # Copy localization files and replace instances of `ReactTestApp` with app display name product_name = display_name || name product_name = if product_name.is_a? String diff --git a/macos/ReactTestApp.xcodeproj/project.pbxproj b/macos/ReactTestApp.xcodeproj/project.pbxproj index 8a436b40f..f6f62e06a 100644 --- a/macos/ReactTestApp.xcodeproj/project.pbxproj +++ b/macos/ReactTestApp.xcodeproj/project.pbxproj @@ -43,7 +43,7 @@ 193EF05F247A736200BE8C79 /* ReactTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 193EF062247A736200BE8C79 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 193EF064247A736200BE8C79 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 193EF066247A736300BE8C79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 193EF066247A736300BE8C79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = SOURCE_ROOT; }; 193EF069247A736300BE8C79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 193EF06B247A736300BE8C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 193EF06C247A736300BE8C79 /* ReactTestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ReactTestApp.entitlements; sourceTree = ""; }; diff --git a/macos/ReactTestApp/Info.plist b/macos/ReactTestApp/Info.plist index 14025d2e0..812287729 100644 --- a/macos/ReactTestApp/Info.plist +++ b/macos/ReactTestApp/Info.plist @@ -8,8 +8,6 @@ $(PRODUCT_DISPLAY_NAME) CFBundleExecutable $(EXECUTABLE_NAME) - CFBundleIconFile - CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion diff --git a/schema.json b/schema.json index d4ef3e552..9f1090a4f 100644 --- a/schema.json +++ b/schema.json @@ -1,5 +1,22 @@ { "$defs": { + "appIconSet": { + "type": "object", + "properties": { + "filename": { + "description": "Path to the app icon file.", + "type": "string" + }, + "prerendered": { + "description": "Whether the icon already incorporates a shine effect.", + "type": "boolean" + } + }, + "required": [ + "filename", + "prerendered" + ] + }, "apple": { "type": "object", "properties": { @@ -12,6 +29,38 @@ "markdownDescription": "Similar to [`version`](#version), but is not shown to users. This is a required\nkey for App Store.\n\nThe equivalent key in `Info.plist` is\n[`CFBundleVersion`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion).\n\nIntroduced in\n[1.4.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.4.0).", "type": "string" }, + "icons": { + "description": "Information about all of the icons used by the app.", + "markdownDescription": "Information about all of the icons used by the app.\n\nIcons for all sizes and scales are generated for you so long as you provide PNGs\nmeasuring 1024x1024 pixels here.\n\nYou can read more about app icons in the\n[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons).\n\nThe equivalent key in `Info.plist` is\n[`CFBundleIcons`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons).\n\nIntroduced in\n[1.6.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.6.0).", + "type": "object", + "properties": { + "primaryIcon": { + "description": "The primary icon for the Home screen and Settings app, among others.", + "markdownDescription": "The primary icon for the Home screen and Settings app, among others.\n\nThe equivalent key in `Info.plist` is\n[`CFBundlePrimaryIcon`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons/cfbundleprimaryicon).", + "allOf": [ + { + "$ref": "#/$defs/appIconSet" + } + ] + }, + "alternateIcons": { + "description": "The primary icon for the Home screen and Settings app, among others.", + "markdownDescription": "The primary icon for the Home screen and Settings app, among others.\n\nThe equivalent key in `Info.plist` is\n[`CFBundleAlternateIcons`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons/cfbundlealternateicons).", + "type": "object", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/$defs/appIconSet" + } + ], + "type": "object" + } + } + }, + "required": [ + "primaryIcon" + ] + }, "codeSignEntitlements": { "description": "Specifies the path to a custom\n[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements)\nfile. The path should be relative to `app.json`.", "markdownDescription": "Specifies the path to a custom\n[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements)\nfile. The path should be relative to `app.json`.\n\nThis is the same as setting `CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in\n[0.9.7](https://github.com/microsoft/react-native-test-app/releases/tag/0.9.7).", @@ -27,8 +76,7 @@ "markdownDescription": "Sets the\ndevelopment\nteam that the app should be assigned to.\n\nThis is the same as setting `DEVELOPMENT_TEAM` in Xcode.\n\nIntroduced in\n[0.9.7](https://github.com/microsoft/react-native-test-app/releases/tag/0.9.7).", "type": "string" } - }, - "exclude-from-codegen": true + } }, "component": { "type": "object", @@ -122,8 +170,7 @@ }, "required": [ "storeFile" - ], - "exclude-from-codegen": true + ] } }, "allOf": [ @@ -192,6 +239,11 @@ "markdownDescription": "A positive integer used as an internal version number. Google uses this number\nto determine whether one version is more recent than another. See\n[Version your app](https://developer.android.com/studio/publish/versioning#appversioning)\nfor more on how it is used and how it differs from [`version`](#version).\n\nIntroduced in\n[1.4.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.4.0).", "type": "string" }, + "icons": { + "description": "Path to resources folder containing launcher icons for the app.", + "markdownDescription": "Path to resources folder containing launcher icons for the app.\n\nIf you're configuring icons for the first time, set this property to the path\nwhere you want to store your icons, then use\n[Image Asset Studio](https://developer.android.com/studio/write/image-asset-studio#access)\nto generate the assets.\n\nYou can read more about Android adaptive icons in the\n[Android documentation](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive).\n\nIntroduced in\n[1.6.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.6.0).", + "type": "string" + }, "signingConfigs": { "description": "Use this to set the\nsigning\nconfigurations for the app.", "markdownDescription": "Use this to set the\nsigning\nconfigurations for the app.\n\nThe JSON schema follows the Gradle DSL very closely. Below is what one would add\nfor the debug and release flavors:\n\n```javascript\n{\n \"android\": {\n \"signingConfigs\": {\n \"debug\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"debug.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n },\n \"release\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"release.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n }\n }\n }\n}\n```\n\nIntroduced in\n[0.11.0](https://github.com/microsoft/react-native-test-app/releases/tag/0.11.0).", diff --git a/scripts/docs/android.icons.md b/scripts/docs/android.icons.md new file mode 100644 index 000000000..40c4058d3 --- /dev/null +++ b/scripts/docs/android.icons.md @@ -0,0 +1,12 @@ +Path to resources folder containing launcher icons for the app. + +If you're configuring icons for the first time, set this property to the path +where you want to store your icons, then use +[Image Asset Studio](https://developer.android.com/studio/write/image-asset-studio#access) +to generate the assets. + +You can read more about Android adaptive icons in the +[Android documentation](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive). + +Introduced in +[1.6.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.6.0). diff --git a/scripts/docs/ios.icons.alternateIcons.md b/scripts/docs/ios.icons.alternateIcons.md new file mode 100644 index 000000000..474d34c05 --- /dev/null +++ b/scripts/docs/ios.icons.alternateIcons.md @@ -0,0 +1,4 @@ +The primary icon for the Home screen and Settings app, among others. + +The equivalent key in `Info.plist` is +[`CFBundleAlternateIcons`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons/cfbundlealternateicons). diff --git a/scripts/docs/ios.icons.md b/scripts/docs/ios.icons.md new file mode 100644 index 000000000..a6ecaaf0b --- /dev/null +++ b/scripts/docs/ios.icons.md @@ -0,0 +1,13 @@ +Information about all of the icons used by the app. + +Icons for all sizes and scales are generated for you so long as you provide PNGs +measuring 1024x1024 pixels here. + +You can read more about app icons in the +[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons). + +The equivalent key in `Info.plist` is +[`CFBundleIcons`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons). + +Introduced in +[1.6.0](https://github.com/microsoft/react-native-test-app/releases/tag/1.6.0). diff --git a/scripts/docs/ios.icons.primaryIcon.md b/scripts/docs/ios.icons.primaryIcon.md new file mode 100644 index 000000000..58a142f44 --- /dev/null +++ b/scripts/docs/ios.icons.primaryIcon.md @@ -0,0 +1,4 @@ +The primary icon for the Home screen and Settings app, among others. + +The equivalent key in `Info.plist` is +[`CFBundlePrimaryIcon`](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons/cfbundleprimaryicon). diff --git a/scripts/generate-schema.mjs b/scripts/generate-schema.mjs index a1a76bf28..d090e945b 100755 --- a/scripts/generate-schema.mjs +++ b/scripts/generate-schema.mjs @@ -48,12 +48,16 @@ export async function generateSchema() { resources: dummy, singleApp: dummy, version: dummy, + "android.icons": dummy, "android.signingConfigs": dummy, "android.versionCode": dummy, "ios.buildNumber": dummy, "ios.codeSignEntitlements": dummy, "ios.codeSignIdentity": dummy, "ios.developmentTeam": dummy, + "ios.icons": dummy, + "ios.icons.primaryIcon": dummy, + "ios.icons.alternateIcons": dummy, "windows.appxManifest": dummy, "windows.certificateKeyFile": dummy, "windows.certificatePassword": dummy, @@ -65,6 +69,22 @@ export async function generateSchema() { return { $defs: { + appIconSet: { + type: "object", + properties: { + filename: { + description: "Path to the app icon file.", + type: "string", + }, + prerendered: { + description: + "Whether the icon already incorporates a shine effect.", + type: "boolean", + }, + }, + required: ["filename", "prerendered"], + "exclude-from-codegen": true, + }, apple: { type: "object", properties: { @@ -78,6 +98,30 @@ export async function generateSchema() { markdownDescription: await docs["ios.buildNumber"], type: "string", }, + icons: { + description: extractBrief(await docs["ios.icons"]), + markdownDescription: await docs["ios.icons"], + type: "object", + properties: { + primaryIcon: { + description: extractBrief(await docs["ios.icons.primaryIcon"]), + markdownDescription: await docs["ios.icons.primaryIcon"], + allOf: [{ $ref: "#/$defs/appIconSet" }], + }, + alternateIcons: { + description: extractBrief( + await docs["ios.icons.alternateIcons"] + ), + markdownDescription: await docs["ios.icons.alternateIcons"], + type: "object", + additionalProperties: { + allOf: [{ $ref: "#/$defs/appIconSet" }], + type: "object", + }, + }, + }, + required: ["primaryIcon"], + }, codeSignEntitlements: { description: extractBrief(await docs["ios.codeSignEntitlements"]), markdownDescription: await docs["ios.codeSignEntitlements"], @@ -239,6 +283,11 @@ export async function generateSchema() { markdownDescription: await docs["android.versionCode"], type: "string", }, + icons: { + description: extractBrief(await docs["android.icons"]), + markdownDescription: await docs["android.icons"], + type: "string", + }, signingConfigs: { description: extractBrief(await docs["android.signingConfigs"]), markdownDescription: await docs["android.signingConfigs"], @@ -321,6 +370,9 @@ export async function generateSchema() { if (process.argv[1] === thisScript) { generateSchema() .then((schema) => { + for (const def of Object.values(schema.$defs)) { + delete def["exclude-from-codegen"]; + } return trimCarriageReturn(JSON.stringify(schema, undefined, 2)) + "\n"; }) .then((schema) => fs.writeFile("schema.json", schema)) diff --git a/scripts/validate-manifest.js b/scripts/validate-manifest.js index ac3587f37..89e7701da 100755 --- a/scripts/validate-manifest.js +++ b/scripts/validate-manifest.js @@ -38,18 +38,8 @@ function findFile(file, startDir = process.cwd()) { } function makeValidator() { - const { default: Ajv, _ } = require("ajv"); + const { default: Ajv } = require("ajv"); const ajv = new Ajv({ allErrors: true }); - ajv.addKeyword({ - keyword: "exclude-from-codegen", - type: "object", - schemaType: "boolean", - code: (cxt) => { - const { data, schema } = cxt; - const op = schema ? _`!==` : _`===`; - cxt.fail(_`${data} %2 ${op} 0`); - }, - }); ajv.addKeyword({ keyword: "markdownDescription" }); return ajv.compile(require(`${__dirname}/../schema.json`)); } diff --git a/test-app.gradle b/test-app.gradle index cef28d4ce..2d9e95b09 100644 --- a/test-app.gradle +++ b/test-app.gradle @@ -137,6 +137,11 @@ ext.applyTestAppModule = { Project project -> main { assets.srcDirs += generatedAssetsDir res.srcDirs += generatedResDir + if (manifest.containsKey("android") && manifest["android"].containsKey("icons")) { + res.srcDirs += "${projectRoot}/${manifest["android"]["icons"]}" + } else { + res.srcDirs += "${testAppDir}/android/app/src/main/res-launcher" + } } } }