@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 +5 -3
- package/build/types.d.ts +6 -0
- package/build/utils/config.js +3 -0
- package/build/withTV.js +6 -2
- package/build/withTVAndroidManifest.d.ts +1 -0
- package/build/withTVAndroidManifest.js +38 -1
- package/build/withTVAppleIconImages.js +44 -13
- package/build/withTVInfoPlist.d.ts +3 -0
- package/build/withTVInfoPlist.js +17 -0
- package/build/withTVXcodeProject.js +17 -17
- package/package.json +1 -1
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
|
|
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.
|
|
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
|
/**
|
package/build/utils/config.js
CHANGED
|
@@ -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,
|
|
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
|
|
40
|
+
const iconSmallSourceImages = [
|
|
41
41
|
{
|
|
42
42
|
path: params.appleTVImages.iconSmall,
|
|
43
43
|
scale: '1x',
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
path: params.appleTVImages.
|
|
46
|
+
path: params.appleTVImages.iconSmall2x,
|
|
47
47
|
scale: '2x',
|
|
48
48
|
},
|
|
49
49
|
];
|
|
50
|
-
const
|
|
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: '
|
|
127
|
+
size: '400x240',
|
|
97
128
|
imageStack: {
|
|
98
|
-
name: 'App Icon -
|
|
129
|
+
name: 'App Icon - Small',
|
|
99
130
|
sourceLayers: [
|
|
100
131
|
{
|
|
101
132
|
name: 'Front',
|
|
102
|
-
sourceImages:
|
|
133
|
+
sourceImages: iconSmallSourceImages,
|
|
103
134
|
},
|
|
104
135
|
{
|
|
105
136
|
name: 'Middle',
|
|
106
|
-
sourceImages:
|
|
137
|
+
sourceImages: iconSmallSourceImages,
|
|
107
138
|
},
|
|
108
139
|
{
|
|
109
140
|
name: 'Back',
|
|
110
|
-
sourceImages:
|
|
141
|
+
sourceImages: iconSmallSourceImages,
|
|
111
142
|
},
|
|
112
143
|
],
|
|
113
144
|
},
|
|
114
145
|
},
|
|
115
146
|
{
|
|
116
147
|
role: 'primary-app-icon',
|
|
117
|
-
size: '
|
|
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:
|
|
154
|
+
sourceImages: iconLargeSourceImages,
|
|
124
155
|
},
|
|
125
156
|
{
|
|
126
157
|
name: 'Middle',
|
|
127
|
-
sourceImages:
|
|
158
|
+
sourceImages: iconLargeSourceImages,
|
|
128
159
|
},
|
|
129
160
|
{
|
|
130
161
|
name: 'Back',
|
|
131
|
-
sourceImages:
|
|
162
|
+
sourceImages: iconLargeSourceImages,
|
|
132
163
|
},
|
|
133
164
|
],
|
|
134
165
|
},
|
|
@@ -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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
buildSettings
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
|
|
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