@fishjam-cloud/react-native-client 0.25.0-rc.1 → 0.25.0-rc.3
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/react-native-client",
|
|
3
|
-
"version": "0.25.0-rc.
|
|
3
|
+
"version": "0.25.0-rc.3",
|
|
4
4
|
"description": "React Native client library for Fishjam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fishjam Team",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"react-native": "src/index.ts",
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/**",
|
|
13
|
-
"plugin/**",
|
|
13
|
+
"plugin/build/**",
|
|
14
|
+
"plugin/broadcastExtensionFiles/**",
|
|
14
15
|
"app.plugin.js"
|
|
15
16
|
],
|
|
16
17
|
"repository": {
|
|
@@ -44,16 +45,16 @@
|
|
|
44
45
|
"react-native": "*"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@fishjam-cloud/react-client": "0.25.0-rc.
|
|
48
|
+
"@fishjam-cloud/react-client": "0.25.0-rc.3",
|
|
48
49
|
"@fishjam-cloud/react-native-webrtc": "git+https://github.com/fishjam-cloud/fishjam-react-native-webrtc.git#9753272f9e6c992d8a05263e668e2198ec858160",
|
|
50
|
+
"promise-fs": "^2.1.1",
|
|
49
51
|
"react-native-get-random-values": "^1.11.0"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@types/promise-fs": "^2.1.2",
|
|
53
55
|
"eslint-config-expo": "~9.2.0",
|
|
54
56
|
"eslint-plugin-prettier": "^5.5.1",
|
|
55
|
-
"expo-module-scripts": "^5.0.7"
|
|
56
|
-
"promise-fs": "^2.1.1"
|
|
57
|
+
"expo-module-scripts": "^5.0.7"
|
|
57
58
|
},
|
|
58
59
|
"packageManager": "yarn@4.12.0",
|
|
59
60
|
"stableVersion": "0.23.0"
|
package/plugin/src/types.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export type FishjamPluginOptions =
|
|
2
|
-
| {
|
|
3
|
-
android?: {
|
|
4
|
-
enableForegroundService?: boolean;
|
|
5
|
-
enableScreensharing?: boolean;
|
|
6
|
-
supportsPictureInPicture?: boolean;
|
|
7
|
-
};
|
|
8
|
-
ios?: {
|
|
9
|
-
enableScreensharing?: boolean;
|
|
10
|
-
supportsPictureInPicture?: boolean;
|
|
11
|
-
broadcastExtensionTargetName?: string;
|
|
12
|
-
broadcastExtensionDisplayName?: string;
|
|
13
|
-
appGroupContainerId?: string;
|
|
14
|
-
mainTargetName?: string;
|
|
15
|
-
iphoneDeploymentTarget?: string;
|
|
16
|
-
enableVoIPBackgroundMode?: boolean;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
| undefined;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
-
|
|
3
|
-
import type { FishjamPluginOptions } from './types';
|
|
4
|
-
import { withFishjamAndroid } from './withFishjamAndroid';
|
|
5
|
-
import { withFishjamIos } from './withFishjamIos';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Main Fishjam Expo config plugin.
|
|
9
|
-
*
|
|
10
|
-
* This plugin configures both iOS and Android platforms for Picture-in-Picture support.
|
|
11
|
-
*
|
|
12
|
-
* ## Usage
|
|
13
|
-
*
|
|
14
|
-
* ```json
|
|
15
|
-
* {
|
|
16
|
-
* "plugins": [
|
|
17
|
-
* [
|
|
18
|
-
* "@fishjam-cloud/react-native-client",
|
|
19
|
-
* {
|
|
20
|
-
* "android": {
|
|
21
|
-
* "supportsPictureInPicture": true
|
|
22
|
-
* },
|
|
23
|
-
* "ios": {
|
|
24
|
-
* "supportsPictureInPicture": true
|
|
25
|
-
* }
|
|
26
|
-
* }
|
|
27
|
-
* ]
|
|
28
|
-
* ]
|
|
29
|
-
* }
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @param config - Expo config object
|
|
33
|
-
* @param options - Plugin configuration options
|
|
34
|
-
* @returns Modified config object
|
|
35
|
-
*/
|
|
36
|
-
const withFishjam: ConfigPlugin<FishjamPluginOptions> = (config, options) => {
|
|
37
|
-
config = withFishjamAndroid(config, options);
|
|
38
|
-
config = withFishjamIos(config, options);
|
|
39
|
-
return config;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default withFishjam;
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
-
import { AndroidConfig, withAndroidManifest } from '@expo/config-plugins';
|
|
3
|
-
import { getMainApplicationOrThrow } from '@expo/config-plugins/build/android/Manifest';
|
|
4
|
-
|
|
5
|
-
import type { FishjamPluginOptions } from './types';
|
|
6
|
-
|
|
7
|
-
const withFishjamPictureInPicture: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
8
|
-
withAndroidManifest(config, (configuration) => {
|
|
9
|
-
const activity = AndroidConfig.Manifest.getMainActivityOrThrow(configuration.modResults);
|
|
10
|
-
|
|
11
|
-
if (props?.android?.supportsPictureInPicture) {
|
|
12
|
-
activity.$['android:supportsPictureInPicture'] = 'true';
|
|
13
|
-
} else {
|
|
14
|
-
delete activity.$['android:supportsPictureInPicture'];
|
|
15
|
-
}
|
|
16
|
-
return configuration;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const withFishjamForegroundService: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
20
|
-
withAndroidManifest(config, async (configuration) => {
|
|
21
|
-
if (!props?.android?.enableForegroundService) {
|
|
22
|
-
return configuration;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const mainApplication = getMainApplicationOrThrow(configuration.modResults);
|
|
26
|
-
mainApplication.service = mainApplication.service || [];
|
|
27
|
-
|
|
28
|
-
const webRTCForegroundService = {
|
|
29
|
-
$: {
|
|
30
|
-
'android:name': 'com.oney.WebRTCModule.foregroundService.WebRTCForegroundService',
|
|
31
|
-
'android:foregroundServiceType': 'camera|microphone',
|
|
32
|
-
'android:stopWithTask': 'true',
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const existingWebRTCForegroundServiceIndex = mainApplication.service.findIndex(
|
|
37
|
-
(service) => service.$['android:name'] === webRTCForegroundService.$['android:name'],
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
if (existingWebRTCForegroundServiceIndex !== -1) {
|
|
41
|
-
mainApplication.service[existingWebRTCForegroundServiceIndex] = webRTCForegroundService;
|
|
42
|
-
} else {
|
|
43
|
-
mainApplication.service.push(webRTCForegroundService);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (props?.android?.enableScreensharing) {
|
|
47
|
-
const mediaProjectionService = {
|
|
48
|
-
$: {
|
|
49
|
-
'android:name': 'com.oney.WebRTCModule.MediaProjectionService',
|
|
50
|
-
'android:foregroundServiceType': 'mediaProjection',
|
|
51
|
-
'android:stopWithTask': 'true',
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const existingMediaProjectionServiceIndex = mainApplication.service.findIndex(
|
|
56
|
-
(service) => service.$['android:name'] === mediaProjectionService.$['android:name'],
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
if (existingMediaProjectionServiceIndex !== -1) {
|
|
60
|
-
mainApplication.service[existingMediaProjectionServiceIndex] = mediaProjectionService;
|
|
61
|
-
} else {
|
|
62
|
-
mainApplication.service.push(mediaProjectionService);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return configuration;
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const withFishjamForegroundServicePermission: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
69
|
-
withAndroidManifest(config, (configuration) => {
|
|
70
|
-
if (!props?.android?.enableForegroundService) {
|
|
71
|
-
return configuration;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const mainApplication = configuration.modResults;
|
|
75
|
-
if (!mainApplication.manifest) {
|
|
76
|
-
return configuration;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!mainApplication.manifest['uses-permission']) {
|
|
80
|
-
mainApplication.manifest['uses-permission'] = [];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const permissions = mainApplication.manifest['uses-permission'];
|
|
84
|
-
|
|
85
|
-
const foregroundServicePermissions = [
|
|
86
|
-
'android.permission.FOREGROUND_SERVICE',
|
|
87
|
-
'android.permission.FOREGROUND_SERVICE_CAMERA',
|
|
88
|
-
'android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION',
|
|
89
|
-
'android.permission.FOREGROUND_SERVICE_MICROPHONE',
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
foregroundServicePermissions.forEach((permissionName) => {
|
|
93
|
-
const hasPermission = permissions.some((perm) => perm.$?.['android:name'] === permissionName);
|
|
94
|
-
|
|
95
|
-
if (!hasPermission) {
|
|
96
|
-
permissions.push({
|
|
97
|
-
$: {
|
|
98
|
-
'android:name': permissionName,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
return configuration;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
export const withFishjamAndroid: ConfigPlugin<FishjamPluginOptions> = (config, props) => {
|
|
108
|
-
config = withFishjamForegroundServicePermission(config, props);
|
|
109
|
-
config = withFishjamForegroundService(config, props);
|
|
110
|
-
config = withFishjamPictureInPicture(config, props);
|
|
111
|
-
return config;
|
|
112
|
-
};
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
-
import { withEntitlementsPlist, withInfoPlist, withPodfileProperties, withXcodeProject } from '@expo/config-plugins';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as fs from 'promise-fs';
|
|
5
|
-
|
|
6
|
-
import type { FishjamPluginOptions } from './types';
|
|
7
|
-
|
|
8
|
-
function getSbeTargetName(props: FishjamPluginOptions) {
|
|
9
|
-
return props?.ios?.broadcastExtensionTargetName || 'ScreenBroadcastExtension';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getSbeDisplayName(props: FishjamPluginOptions) {
|
|
13
|
-
return props?.ios?.broadcastExtensionDisplayName || 'ScreenBroadcast';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
17
|
-
const IPHONEOS_DEPLOYMENT_TARGET = '15.1';
|
|
18
|
-
const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
19
|
-
const BUNDLE_IDENTIFIER_TEMPLATE_REGEX = /{{BUNDLE_IDENTIFIER}}/gm;
|
|
20
|
-
const DISPLAY_NAME_TEMPLATE_REGEX = /{{DISPLAY_NAME}}/gm;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A helper function for updating a value in a file for given regex
|
|
24
|
-
*/
|
|
25
|
-
async function updateFileWithRegex(
|
|
26
|
-
iosPath: string,
|
|
27
|
-
fileName: string,
|
|
28
|
-
regex: RegExp,
|
|
29
|
-
value: string,
|
|
30
|
-
props: FishjamPluginOptions,
|
|
31
|
-
) {
|
|
32
|
-
const targetName = getSbeTargetName(props);
|
|
33
|
-
const filePath = `${iosPath}/${targetName}/${fileName}`;
|
|
34
|
-
let file = await fs.readFile(filePath, { encoding: 'utf-8' });
|
|
35
|
-
file = file.replace(regex, value);
|
|
36
|
-
await fs.writeFile(filePath, file);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Adds "App Group" permission
|
|
41
|
-
* App Group allows your app and the ScreenBroadcastExtension to communicate with each other.
|
|
42
|
-
*/
|
|
43
|
-
const withAppGroupPermissions: ConfigPlugin<FishjamPluginOptions> = (config, props) => {
|
|
44
|
-
const APP_GROUP_KEY = 'com.apple.security.application-groups';
|
|
45
|
-
const bundleIdentifier = config.ios?.bundleIdentifier || '';
|
|
46
|
-
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
47
|
-
const mainTarget = props?.ios?.mainTargetName || '';
|
|
48
|
-
|
|
49
|
-
config.ios ??= {};
|
|
50
|
-
config.ios.entitlements ??= {};
|
|
51
|
-
config.ios.entitlements[APP_GROUP_KEY] ??= [];
|
|
52
|
-
|
|
53
|
-
const entitlementsArray = config.ios.entitlements[APP_GROUP_KEY] as string[];
|
|
54
|
-
if (!entitlementsArray.includes(groupIdentifier)) {
|
|
55
|
-
entitlementsArray.push(groupIdentifier);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
config = withEntitlementsPlist(config, (newConfig) => {
|
|
59
|
-
const modResultsArray = (newConfig.modResults[APP_GROUP_KEY] as string[]) || [];
|
|
60
|
-
if (!modResultsArray.includes(groupIdentifier)) {
|
|
61
|
-
modResultsArray.push(groupIdentifier);
|
|
62
|
-
}
|
|
63
|
-
newConfig.modResults[APP_GROUP_KEY] = modResultsArray;
|
|
64
|
-
return newConfig;
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// eslint-disable-next-line no-shadow
|
|
68
|
-
config = withXcodeProject(config, (props) => {
|
|
69
|
-
const xcodeProject = props.modResults;
|
|
70
|
-
const targets = xcodeProject.getFirstTarget();
|
|
71
|
-
const project = xcodeProject.getFirstProject();
|
|
72
|
-
|
|
73
|
-
if (!targets || !project) {
|
|
74
|
-
return props;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const targetUuid = targets.uuid;
|
|
78
|
-
const projectUuid = project.uuid;
|
|
79
|
-
|
|
80
|
-
const projectObj = xcodeProject.hash.project.objects.PBXProject[projectUuid];
|
|
81
|
-
projectObj.attributes ??= {};
|
|
82
|
-
projectObj.attributes.TargetAttributes ??= {};
|
|
83
|
-
projectObj.attributes.TargetAttributes[targetUuid] ??= {};
|
|
84
|
-
projectObj.attributes.TargetAttributes[targetUuid].SystemCapabilities ??= {};
|
|
85
|
-
|
|
86
|
-
projectObj.attributes.TargetAttributes[targetUuid].SystemCapabilities['com.apple.ApplicationGroups.iOS'] = {
|
|
87
|
-
enabled: 1,
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const mainTargetName = mainTarget || props.modRequest.projectName;
|
|
91
|
-
const entitlementsFilePath = `${mainTargetName}/${mainTargetName}.entitlements`;
|
|
92
|
-
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
93
|
-
|
|
94
|
-
Object.keys(configurations).forEach((key) => {
|
|
95
|
-
// eslint-disable-next-line no-shadow
|
|
96
|
-
const config = configurations[key];
|
|
97
|
-
if (config.buildSettings?.PRODUCT_NAME?.includes(mainTargetName)) {
|
|
98
|
-
if (!config.buildSettings.CODE_SIGN_ENTITLEMENTS) {
|
|
99
|
-
config.buildSettings.CODE_SIGN_ENTITLEMENTS = entitlementsFilePath;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
return props;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return config;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Adds constants to Info.plist
|
|
112
|
-
* In order to dynamically retrieve extension's bundleId and group name we need to store it in Info.plist.
|
|
113
|
-
*/
|
|
114
|
-
const withInfoPlistConstants: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
115
|
-
withInfoPlist(config, (configuration) => {
|
|
116
|
-
const bundleIdentifier = configuration.ios?.bundleIdentifier || '';
|
|
117
|
-
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
118
|
-
configuration.modResults['RTCScreenSharingExtension'] = `${bundleIdentifier}.${getSbeTargetName(props)}`;
|
|
119
|
-
configuration.modResults['RTCAppGroupIdentifier'] = groupIdentifier;
|
|
120
|
-
return configuration;
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Updates and copies required extension files.
|
|
125
|
-
* Our extension needs to be properly setup inside the Xcode project. In order to do that we need to copy the files and update the pbxproj.
|
|
126
|
-
*/
|
|
127
|
-
const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
|
|
128
|
-
withXcodeProject(config, async (props) => {
|
|
129
|
-
const appName = props.modRequest.projectName || '';
|
|
130
|
-
const iosPath = props.modRequest.platformProjectRoot;
|
|
131
|
-
const bundleIdentifier = props.ios?.bundleIdentifier;
|
|
132
|
-
const groupIdentifier = options?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
133
|
-
const xcodeProject = props.modResults;
|
|
134
|
-
const targetName = getSbeTargetName(options);
|
|
135
|
-
|
|
136
|
-
const pluginDir = require.resolve('@fishjam-cloud/react-native-client/package.json');
|
|
137
|
-
const extensionSourceDir = path.join(pluginDir, '../plugin/broadcastExtensionFiles/');
|
|
138
|
-
|
|
139
|
-
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
140
|
-
const templateTargetName = 'ScreenBroadcastExtension';
|
|
141
|
-
|
|
142
|
-
const extFiles = [
|
|
143
|
-
'SampleHandler.swift',
|
|
144
|
-
'SampleUploader.swift',
|
|
145
|
-
`${templateTargetName}.entitlements`,
|
|
146
|
-
`Info.plist`,
|
|
147
|
-
'SocketConnection.swift',
|
|
148
|
-
'DarwinNotificationCenter.swift',
|
|
149
|
-
'Atomic.swift',
|
|
150
|
-
];
|
|
151
|
-
|
|
152
|
-
const destFiles = [
|
|
153
|
-
'SampleHandler.swift',
|
|
154
|
-
'SampleUploader.swift',
|
|
155
|
-
`${targetName}.entitlements`,
|
|
156
|
-
`Info.plist`,
|
|
157
|
-
'SocketConnection.swift',
|
|
158
|
-
'DarwinNotificationCenter.swift',
|
|
159
|
-
'Atomic.swift',
|
|
160
|
-
];
|
|
161
|
-
|
|
162
|
-
await xcodeProject.parse(async function (err: Error) {
|
|
163
|
-
if (err) {
|
|
164
|
-
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
if (xcodeProject.pbxTargetByName(targetName)) {
|
|
168
|
-
// eslint-disable-next-line no-console
|
|
169
|
-
console.log(`${targetName} already exists in project. Skipping...`);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
try {
|
|
173
|
-
await fs.mkdir(`${iosPath}/${targetName}`, { recursive: true });
|
|
174
|
-
for (let i = 0; i < extFiles.length; i++) {
|
|
175
|
-
const srcFile = `${extensionSourceDir}${extFiles[i]}`;
|
|
176
|
-
const destFile = `${iosPath}/${targetName}/${destFiles[i]}`;
|
|
177
|
-
await fs.copyFile(srcFile, destFile);
|
|
178
|
-
}
|
|
179
|
-
} catch (e) {
|
|
180
|
-
console.error('Error copying extension files: ', e);
|
|
181
|
-
throw e;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
await updateFileWithRegex(
|
|
186
|
-
iosPath,
|
|
187
|
-
`${targetName}.entitlements`,
|
|
188
|
-
GROUP_IDENTIFIER_TEMPLATE_REGEX,
|
|
189
|
-
groupIdentifier,
|
|
190
|
-
options,
|
|
191
|
-
);
|
|
192
|
-
await updateFileWithRegex(
|
|
193
|
-
iosPath,
|
|
194
|
-
'SampleHandler.swift',
|
|
195
|
-
GROUP_IDENTIFIER_TEMPLATE_REGEX,
|
|
196
|
-
groupIdentifier,
|
|
197
|
-
options,
|
|
198
|
-
);
|
|
199
|
-
await updateFileWithRegex(
|
|
200
|
-
iosPath,
|
|
201
|
-
'SampleUploader.swift',
|
|
202
|
-
BUNDLE_IDENTIFIER_TEMPLATE_REGEX,
|
|
203
|
-
bundleIdentifier || '',
|
|
204
|
-
options,
|
|
205
|
-
);
|
|
206
|
-
await updateFileWithRegex(
|
|
207
|
-
iosPath,
|
|
208
|
-
'Info.plist',
|
|
209
|
-
DISPLAY_NAME_TEMPLATE_REGEX,
|
|
210
|
-
getSbeDisplayName(options),
|
|
211
|
-
options,
|
|
212
|
-
);
|
|
213
|
-
} catch (e) {
|
|
214
|
-
console.error('Error updating extension files: ', e);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Create new PBXGroup for the extension
|
|
218
|
-
const extGroup = xcodeProject.addPbxGroup(extFiles, targetName, targetName);
|
|
219
|
-
|
|
220
|
-
// Add the new PBXGroup to the top level group. This makes the
|
|
221
|
-
// files / folder appear in the file explorer in Xcode.
|
|
222
|
-
const groups = xcodeProject.hash.project.objects['PBXGroup'];
|
|
223
|
-
Object.keys(groups).forEach(function (key) {
|
|
224
|
-
if (groups[key].name === undefined) {
|
|
225
|
-
xcodeProject.addToPbxGroup(extGroup.uuid, key);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// WORK AROUND for codeProject.addTarget BUG
|
|
230
|
-
// Xcode projects don't contain these if there is only one target
|
|
231
|
-
// An upstream fix should be made to the code referenced in this link:
|
|
232
|
-
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
233
|
-
const projObjects = xcodeProject.hash.project.objects;
|
|
234
|
-
projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
|
|
235
|
-
projObjects['PBXContainerItemProxy'] = projObjects['PBXContainerItemProxy'] || {};
|
|
236
|
-
|
|
237
|
-
// Add the SBE target
|
|
238
|
-
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
239
|
-
const sbeTarget = xcodeProject.addTarget(
|
|
240
|
-
targetName,
|
|
241
|
-
'app_extension',
|
|
242
|
-
targetName,
|
|
243
|
-
`${bundleIdentifier}.${targetName}`,
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
// Add build phases to the new target
|
|
247
|
-
xcodeProject.addBuildPhase(
|
|
248
|
-
[
|
|
249
|
-
'SampleHandler.swift',
|
|
250
|
-
'SampleUploader.swift',
|
|
251
|
-
'SocketConnection.swift',
|
|
252
|
-
'DarwinNotificationCenter.swift',
|
|
253
|
-
'Atomic.swift',
|
|
254
|
-
],
|
|
255
|
-
'PBXSourcesBuildPhase',
|
|
256
|
-
'Sources',
|
|
257
|
-
sbeTarget.uuid,
|
|
258
|
-
);
|
|
259
|
-
xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', sbeTarget.uuid);
|
|
260
|
-
|
|
261
|
-
xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', sbeTarget.uuid);
|
|
262
|
-
|
|
263
|
-
xcodeProject.addFramework('ReplayKit.framework', {
|
|
264
|
-
target: sbeTarget.uuid,
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
|
|
268
|
-
// However, can be more
|
|
269
|
-
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
270
|
-
for (const key in configurations) {
|
|
271
|
-
if (
|
|
272
|
-
typeof configurations[key].buildSettings !== 'undefined' &&
|
|
273
|
-
configurations[key].buildSettings.PRODUCT_NAME === `"${targetName}"`
|
|
274
|
-
) {
|
|
275
|
-
const buildSettingsObj = configurations[key].buildSettings;
|
|
276
|
-
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
|
|
277
|
-
options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
278
|
-
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
279
|
-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
|
|
280
|
-
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
|
|
281
|
-
buildSettingsObj.INFOPLIST_FILE = `${targetName}/Info.plist`;
|
|
282
|
-
buildSettingsObj.SWIFT_VERSION = '5.0';
|
|
283
|
-
buildSettingsObj.MARKETING_VERSION = '1.0.0';
|
|
284
|
-
buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
|
|
285
|
-
buildSettingsObj.ENABLE_BITCODE = 'NO';
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
await fs.writeFile(projPath, xcodeProject.writeSync());
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
return props;
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Adds iOS VoIP background mode to keep the app running during calls
|
|
297
|
-
*/
|
|
298
|
-
const withFishjamVoIPBackgroundMode: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
299
|
-
withInfoPlist(config, (configuration) => {
|
|
300
|
-
if (props?.ios?.enableVoIPBackgroundMode) {
|
|
301
|
-
const backgroundModes = new Set(configuration.modResults.UIBackgroundModes ?? []);
|
|
302
|
-
backgroundModes.add('voip');
|
|
303
|
-
|
|
304
|
-
configuration.modResults.UIBackgroundModes = Array.from(backgroundModes);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return configuration;
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
const withFishjamPictureInPicture: ConfigPlugin<FishjamPluginOptions> = (config, props) =>
|
|
311
|
-
withInfoPlist(config, (configuration) => {
|
|
312
|
-
if (props?.ios?.supportsPictureInPicture) {
|
|
313
|
-
const backgroundModes = new Set(configuration.modResults.UIBackgroundModes ?? []);
|
|
314
|
-
backgroundModes.add('audio');
|
|
315
|
-
configuration.modResults.UIBackgroundModes = Array.from(backgroundModes);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return configuration;
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
const withFishjamIos: ConfigPlugin<FishjamPluginOptions> = (config, props) => {
|
|
322
|
-
if (props?.ios?.enableScreensharing) {
|
|
323
|
-
config = withAppGroupPermissions(config, props);
|
|
324
|
-
config = withInfoPlistConstants(config, props);
|
|
325
|
-
config = withFishjamSBE(config, props);
|
|
326
|
-
}
|
|
327
|
-
config = withPodfileProperties(config, (configuration) => {
|
|
328
|
-
configuration.modResults['ios.deploymentTarget'] = props?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
329
|
-
return configuration;
|
|
330
|
-
});
|
|
331
|
-
config = withFishjamPictureInPicture(config, props);
|
|
332
|
-
config = withFishjamVoIPBackgroundMode(config, props);
|
|
333
|
-
return config;
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
export { withFishjamIos };
|
package/plugin/tsconfig.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./src/types.ts","./src/withFishjam.ts","./src/withFishjamAndroid.ts","./src/withFishjamIos.ts"],"version":"5.8.3"}
|