@react-native-tvos/config-tv 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -42,6 +42,7 @@ or
42
42
  "appleTVImages": {
43
43
  "icon": "./assets/images/myimage-tvos-1280x768.png",
44
44
  "iconSmall": "./assets/images/myimage-tvos-400x240.png",
45
+ "iconSmall2x": "./assets/images/myimage-tvos-800x480.png",
45
46
  "topShelf": "./assets/images/myimage-tvos-1920x720.png",
46
47
  "topShelf2x": "./assets/images/myimage-tvos-3840x1440.png",
47
48
  "topShelfWide": "./assets/images/myimage-tvos-2320x720.png",
@@ -64,11 +65,12 @@ _Plugin parameters_:
64
65
  - `DEBUG=expo:*` (shows debug messages from all plugins)
65
66
  - `DEBUG=expo:react-native-tvos:config-tv` (shows debug messages from this plugin only)
66
67
  - `tvosDeploymentTarget`: (optional string, default '13.4') Used to set the tvOS deployment target version in the Xcode project.
67
- - `removeFlipperOnAndroid`: (optional boolean, default true) Used to remove the Flipper dependency from `MainApplication.kt` (or `MainApplication.java`) and `android/app/build.gradle`. This is necessary for React Native TV 0.73 and higher, since Flipper integration is removed from these versions. If this causes issues, set the value to false, run `npx expo prebuild --clean` again, and then remove Flipper from your Android source manually.
68
+ - `removeFlipperOnAndroid`: (optional boolean, default true) Used to remove the Flipper dependency from `MainApplication.kt` (or `MainApplication.java`) and `android/app/build.gradle`. This is necessary for React Native TV 0.73 and higher, since Flipper integration is removed from these versions. If this causes issues, set the value to false, run `npx expo prebuild --clean` again, and then remove Flipper from your Android source manually. This change will be made regardless of the setting of the `EXPO_TV` environment variable or the value of the `isTV` plugin parameter, as it is needed for both Android mobile and Android TV.
68
69
  - `androidTVBanner`: (optional string) If set, this should be a path to an existing PNG file appropriate for an Android TV banner image. See https://developer.android.com/design/ui/tv/guides/system/tv-app-icon-guidelines#banner . The Android manifest will be modified to reference this image, and the image will be copied into Android resource drawable directories.
69
- - `appleTVImages`: (optional object) If set, this is an object with the paths to images needed to construct the Apple TV icon and top shelf brand assets. The images will be used to construct a brand asset catalog in the Xcode project Image catalog, and the project updated to use the brand assets as the source for the app icons. If this property is set, all six image paths must be defined and the files must exist, or an error will be thrown. The images need to be the exact sizes shown here, in order to avoid errors during Xcode compilation and on submission to the App Store or TestFlight.
70
+ - `appleTVImages`: (optional object) If set, this is an object with the paths to images needed to construct the Apple TV icon and top shelf brand assets. The images will be used to construct a brand asset catalog in the Xcode project Image catalog, and the project updated to use the brand assets as the source for the app icons. If this property is set, all image paths must be defined and the files must exist, or an error will be thrown. The images need to be the exact sizes shown here, in order to avoid errors during Xcode compilation and on submission to the App Store or TestFlight.
70
71
  - `icon`: (string) Path to a 1280x760 image
71
72
  - `iconSmall`: (string) Path to a 400x240 image
73
+ - `iconSmall2x`: (string) Path to a 800x480 image
72
74
  - `topShelf`: (string) Path to a 1920x720 image
73
75
  - `topShelf2x`: (string) Path to a 3840x1440 image
74
76
  - `topShelfWide`: (string) Path to a 2320x720 image
@@ -81,7 +83,7 @@ When this plugin is used to generate files in the iOS directory that build an Ap
81
83
  ```json
82
84
  {
83
85
  "dependencies": {
84
- "react-native": "npm:react-native-tvos@^0.73.2-0"
86
+ "react-native": "npm:react-native-tvos@^0.73.6-0"
85
87
  }
86
88
  }
87
89
  ```
package/build/types.d.ts CHANGED
@@ -3,6 +3,10 @@ export type AppleTVImages = {
3
3
  * Path to 400x240 image
4
4
  */
5
5
  iconSmall: string;
6
+ /**
7
+ * Path to 800x480 image
8
+ */
9
+ iconSmall2x: string;
6
10
  /**
7
11
  * Path to 1280x760 image
8
12
  */
@@ -47,6 +51,8 @@ export type ConfigData = {
47
51
  tvosDeploymentTarget?: string;
48
52
  /**
49
53
  * If set, Android code that references Flipper will be removed. (Defaults to true.)
54
+ * This change will be made regardless of the setting of the `EXPO_TV` environment variable or
55
+ * the value of the `isTV` plugin parameter, as it is needed for both Android mobile and Android TV.
50
56
  */
51
57
  removeFlipperOnAndroid?: boolean;
52
58
  /**
@@ -31,6 +31,7 @@ exports.androidTVBanner = androidTVBanner;
31
31
  exports.appleTVImageTypes = [
32
32
  'icon',
33
33
  'iconSmall',
34
+ 'iconSmall2x',
34
35
  'topShelf',
35
36
  'topShelf2x',
36
37
  'topShelfWide',
@@ -42,6 +43,8 @@ function appleTVImagePathForType(params, imageType) {
42
43
  return params?.appleTVImages?.icon;
43
44
  case 'iconSmall':
44
45
  return params?.appleTVImages?.iconSmall;
46
+ case 'iconSmall2x':
47
+ return params?.appleTVImages?.iconSmall2x;
45
48
  case 'topShelf':
46
49
  return params?.appleTVImages?.topShelf;
47
50
  case 'topShelf2x':
package/build/withTV.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_plugins_1 = require("expo/config-plugins");
4
4
  const withTVAndroidManifest_1 = require("./withTVAndroidManifest");
5
5
  const withTVAppleIconImages_1 = require("./withTVAppleIconImages");
6
+ const withTVInfoPlist_1 = require("./withTVInfoPlist");
6
7
  const withTVPodfile_1 = require("./withTVPodfile");
7
8
  const withTVSplashScreen_1 = require("./withTVSplashScreen");
8
9
  const withTVXcodeProject_1 = require("./withTVXcodeProject");
@@ -10,10 +11,13 @@ const withTVAndroidRemoveFlipper_1 = require("./withTVAndroidRemoveFlipper");
10
11
  const withTVAndroidBannerImage_1 = require("./withTVAndroidBannerImage");
11
12
  const utils_1 = require("./utils");
12
13
  const withTVNoEffect = (config, params = {}) => {
13
- (0, utils_1.verboseLog)(`${utils_1.packageNameAndVersion}: isTV == false, plugin will have no effect`, {});
14
+ (0, utils_1.verboseLog)(`${utils_1.packageNameAndVersion}: isTV == false, TV-specific modifications will not be made.`, {});
14
15
  return config;
15
16
  };
16
17
  const withTVPlugin = (config, params = {}) => {
18
+ // This plugin should always run
19
+ config = (0, withTVAndroidRemoveFlipper_1.withTVAndroidRemoveFlipper)(config, params);
20
+ // Return if TV is not enabled
17
21
  const isTV = (0, utils_1.isTVEnabled)(params);
18
22
  if (!isTV) {
19
23
  config = withTVNoEffect(config, params);
@@ -22,10 +26,10 @@ const withTVPlugin = (config, params = {}) => {
22
26
  config = (0, withTVAppleIconImages_1.withTVAppleIconImages)(config, params); // This should be done before Apple Xcode project config
23
27
  config = (0, withTVXcodeProject_1.withTVXcodeProject)(config, params);
24
28
  config = (0, withTVPodfile_1.withTVPodfile)(config, params);
29
+ config = (0, withTVInfoPlist_1.withTVInfoPlist)(config, params);
25
30
  config = (0, withTVSplashScreen_1.withTVSplashScreen)(config, params);
26
31
  config = (0, withTVAndroidBannerImage_1.withTVAndroidBannerImage)(config, params); // This should be done before Android manifest config
27
32
  config = (0, withTVAndroidManifest_1.withTVAndroidManifest)(config, params);
28
- config = (0, withTVAndroidRemoveFlipper_1.withTVAndroidRemoveFlipper)(config, params);
29
33
  return config;
30
34
  };
31
35
  const pkg = require('../package.json');
@@ -5,3 +5,4 @@ export declare const withTVAndroidManifest: ConfigPlugin<ConfigData>;
5
5
  export declare function setLeanBackLauncherIntent(_config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidConfig.Manifest.AndroidManifest, params: ConfigData): AndroidConfig.Manifest.AndroidManifest;
6
6
  export declare function removePortraitOrientation(_config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidConfig.Manifest.AndroidManifest, params: ConfigData): AndroidConfig.Manifest.AndroidManifest;
7
7
  export declare function setTVBanner(_config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidConfig.Manifest.AndroidManifest, params: ConfigData, androidTVBannerPath: string | undefined): AndroidConfig.Manifest.AndroidManifest;
8
+ export declare function addTouchscreenHardwareFeatureToManifest(_config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidConfig.Manifest.AndroidManifest, params: ConfigData): AndroidConfig.Manifest.AndroidManifest;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setTVBanner = exports.removePortraitOrientation = exports.setLeanBackLauncherIntent = exports.withTVAndroidManifest = void 0;
3
+ exports.addTouchscreenHardwareFeatureToManifest = exports.setTVBanner = exports.removePortraitOrientation = exports.setLeanBackLauncherIntent = exports.withTVAndroidManifest = void 0;
4
4
  const config_plugins_1 = require("expo/config-plugins");
5
5
  const utils_1 = require("./utils");
6
6
  const { getMainActivity, getMainApplication } = config_plugins_1.AndroidConfig.Manifest;
@@ -9,6 +9,7 @@ const withTVAndroidManifest = (config, params = {}) => {
9
9
  return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
10
10
  config.modResults = setLeanBackLauncherIntent(config, config.modResults, params);
11
11
  config.modResults = removePortraitOrientation(config, config.modResults, params);
12
+ config.modResults = addTouchscreenHardwareFeatureToManifest(config, config.modResults, params);
12
13
  if (androidTVBannerPath) {
13
14
  config.modResults = setTVBanner(config, config.modResults, params, androidTVBannerPath);
14
15
  }
@@ -90,3 +91,39 @@ function setTVBanner(_config, androidManifest, params, androidTVBannerPath) {
90
91
  return androidManifest;
91
92
  }
92
93
  exports.setTVBanner = setTVBanner;
94
+ function addTouchscreenHardwareFeatureToManifest(_config, androidManifest, params) {
95
+ // Add `<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>` to the AndroidManifest.xml
96
+ if (!Array.isArray(androidManifest.manifest['uses-feature'])) {
97
+ androidManifest.manifest['uses-feature'] = [];
98
+ }
99
+ if (!androidManifest.manifest['uses-feature'].find((item) => item.$['android:name'] === 'android.hardware.touchscreen') &&
100
+ !androidManifest.manifest['uses-feature'].find((item) => item.$['android:name'] === 'android.hardware.faketouch') &&
101
+ !androidManifest.manifest['uses-feature'].find((item) => item.$['android:name'] === 'android.software.leanback')) {
102
+ (0, utils_1.verboseLog)('adding TV touchscreen hardware feature tag to AndroidManifest.xml', {
103
+ params,
104
+ platform: 'android',
105
+ property: 'manifest',
106
+ });
107
+ androidManifest.manifest['uses-feature']?.push({
108
+ $: {
109
+ 'android:name': 'android.hardware.touchscreen',
110
+ 'android:required': 'false',
111
+ },
112
+ });
113
+ androidManifest.manifest['uses-feature']?.push({
114
+ $: {
115
+ 'android:name': 'android.hardware.faketouch',
116
+ 'android:required': 'false',
117
+ },
118
+ });
119
+ // add android.software.leanback to false
120
+ androidManifest.manifest['uses-feature']?.push({
121
+ $: {
122
+ 'android:name': 'android.software.leanback',
123
+ 'android:required': 'false',
124
+ },
125
+ });
126
+ }
127
+ return androidManifest;
128
+ }
129
+ exports.addTouchscreenHardwareFeatureToManifest = addTouchscreenHardwareFeatureToManifest;
@@ -37,21 +37,29 @@ const withTVAppleIconImages = (c, params = {}) => {
37
37
  });
38
38
  const projectRoot = config.modRequest.projectRoot;
39
39
  const iosImagesPath = path_1.default.join(getIosNamedProjectPath(projectRoot), IMAGES_PATH);
40
- const iconSourceImages = [
40
+ const iconSmallSourceImages = [
41
41
  {
42
42
  path: params.appleTVImages.iconSmall,
43
43
  scale: '1x',
44
44
  },
45
45
  {
46
- path: params.appleTVImages.icon,
46
+ path: params.appleTVImages.iconSmall2x,
47
47
  scale: '2x',
48
48
  },
49
49
  ];
50
- const appStoreIconSourceImages = [
50
+ const iconLargeSourceImages = [
51
51
  {
52
52
  path: params.appleTVImages.icon,
53
+ scale: '1x',
53
54
  },
54
55
  ];
56
+ /*
57
+ const appStoreIconSourceImages: SourceImageJson[] = [
58
+ {
59
+ path: params.appleTVImages.icon,
60
+ },
61
+ ];
62
+ */
55
63
  const topShelfSourceImages = [
56
64
  {
57
65
  path: params.appleTVImages.topShelf,
@@ -91,44 +99,67 @@ const withTVAppleIconImages = (c, params = {}) => {
91
99
  sourceImages: topShelfWideSourceImages,
92
100
  },
93
101
  },
102
+ /*
103
+ {
104
+ role: 'primary-app-icon',
105
+ size: '1280x768',
106
+ imageStack: {
107
+ name: 'App Icon - App Store',
108
+ sourceLayers: [
109
+ {
110
+ name: 'Front',
111
+ sourceImages: appStoreIconSourceImages,
112
+ },
113
+ {
114
+ name: 'Middle',
115
+ sourceImages: appStoreIconSourceImages,
116
+ },
117
+ {
118
+ name: 'Back',
119
+ sourceImages: appStoreIconSourceImages,
120
+ },
121
+ ],
122
+ },
123
+ },
124
+ */
94
125
  {
95
126
  role: 'primary-app-icon',
96
- size: '1280x768',
127
+ size: '400x240',
97
128
  imageStack: {
98
- name: 'App Icon - App Store',
129
+ name: 'App Icon - Small',
99
130
  sourceLayers: [
100
131
  {
101
132
  name: 'Front',
102
- sourceImages: appStoreIconSourceImages,
133
+ sourceImages: iconSmallSourceImages,
103
134
  },
104
135
  {
105
136
  name: 'Middle',
106
- sourceImages: appStoreIconSourceImages,
137
+ sourceImages: iconSmallSourceImages,
107
138
  },
108
139
  {
109
140
  name: 'Back',
110
- sourceImages: appStoreIconSourceImages,
141
+ sourceImages: iconSmallSourceImages,
111
142
  },
112
143
  ],
113
144
  },
114
145
  },
115
146
  {
116
147
  role: 'primary-app-icon',
117
- size: '400x240',
148
+ size: '1280x768',
118
149
  imageStack: {
119
- name: 'App Icon',
150
+ name: 'App Icon - Large',
120
151
  sourceLayers: [
121
152
  {
122
153
  name: 'Front',
123
- sourceImages: iconSourceImages,
154
+ sourceImages: iconLargeSourceImages,
124
155
  },
125
156
  {
126
157
  name: 'Middle',
127
- sourceImages: iconSourceImages,
158
+ sourceImages: iconLargeSourceImages,
128
159
  },
129
160
  {
130
161
  name: 'Back',
131
- sourceImages: iconSourceImages,
162
+ sourceImages: iconLargeSourceImages,
132
163
  },
133
164
  ],
134
165
  },
@@ -0,0 +1,3 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ import { ConfigData } from './types';
3
+ export declare const withTVInfoPlist: ConfigPlugin<ConfigData>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withTVInfoPlist = void 0;
4
+ const config_plugins_1 = require("expo/config-plugins");
5
+ const utils_1 = require("./utils");
6
+ const withTVInfoPlist = (c, params = {}) => {
7
+ (0, utils_1.verboseLog)('Modifying UIRequiredDeviceCapabilities for TV', {
8
+ params,
9
+ platform: 'ios',
10
+ property: 'Info.plist',
11
+ });
12
+ return (0, config_plugins_1.withInfoPlist)(c, (config) => {
13
+ config.modResults.UIRequiredDeviceCapabilities = ['arm64'];
14
+ return config;
15
+ });
16
+ };
17
+ exports.withTVInfoPlist = withTVInfoPlist;
@@ -21,24 +21,24 @@ function setXcodeProjectBuildSettings(config, { project, params, deploymentTarge
21
21
  for (const { buildSettings } of Object.values(configurations || {})) {
22
22
  // Guessing that this is the best way to emulate Xcode.
23
23
  // Using `project.addToBuildSettings` modifies too many targets.
24
+ if (buildSettings !== undefined) {
25
+ buildSettings.SDKROOT = 'appletvos';
26
+ }
24
27
  if (typeof buildSettings?.PRODUCT_NAME !== 'undefined') {
25
- if (buildSettings.TARGETED_DEVICE_FAMILY !== '3') {
26
- (0, utils_1.verboseLog)(`modifying target ${buildSettings?.PRODUCT_NAME} for tvOS`, {
27
- params,
28
- platform: 'ios',
29
- property: 'xcodeproject',
30
- });
31
- buildSettings.TARGETED_DEVICE_FAMILY = '3';
32
- buildSettings.TVOS_DEPLOYMENT_TARGET = deploymentTarget;
33
- buildSettings.SDKROOT = 'appletvos';
34
- if (typeof buildSettings?.IOS_DEPLOYMENT_TARGET !== 'undefined') {
35
- delete buildSettings?.IOS_DEPLOYMENT_TARGET;
36
- }
37
- if (params.appleTVImages) {
38
- // set the app icon source
39
- if (buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME === 'AppIcon') {
40
- buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME = 'TVAppIcon';
41
- }
28
+ (0, utils_1.verboseLog)(`modifying target ${buildSettings?.PRODUCT_NAME} for tvOS`, {
29
+ params,
30
+ platform: 'ios',
31
+ property: 'xcodeproject',
32
+ });
33
+ buildSettings.TARGETED_DEVICE_FAMILY = '3';
34
+ buildSettings.TVOS_DEPLOYMENT_TARGET = deploymentTarget;
35
+ if (typeof buildSettings?.IOS_DEPLOYMENT_TARGET !== 'undefined') {
36
+ delete buildSettings?.IOS_DEPLOYMENT_TARGET;
37
+ }
38
+ if (params.appleTVImages) {
39
+ // set the app icon source
40
+ if (buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME === 'AppIcon') {
41
+ buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME = 'TVAppIcon';
42
42
  }
43
43
  }
44
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-tvos/config-tv",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Config plugin to reconfigure native directories for Apple TV and Android TV development if needed",
5
5
  "main": "build/withTV.js",
6
6
  "types": "build/withTV.d.ts",