@fishjam-cloud/react-native-client 0.18.1 → 0.19.1
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 +1 -1
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +25 -15
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +52 -0
- package/build/RNFishjamClientModule.d.ts +6 -1
- package/build/RNFishjamClientModule.d.ts.map +1 -1
- package/build/RNFishjamClientModule.js.map +1 -1
- package/build/components/FishjamRoom/index.d.ts +6 -0
- package/build/components/FishjamRoom/index.d.ts.map +1 -1
- package/build/components/FishjamRoom/index.js +6 -0
- package/build/components/FishjamRoom/index.js.map +1 -1
- package/build/components/LivestreamView.d.ts +33 -1
- package/build/components/LivestreamView.d.ts.map +1 -1
- package/build/components/LivestreamView.js +1 -1
- package/build/components/LivestreamView.js.map +1 -1
- package/build/components/VideoPreviewView.d.ts +1 -1
- package/build/components/VideoPreviewView.js +1 -0
- package/build/components/VideoPreviewView.js.map +1 -1
- package/build/components/VideoRendererView.d.ts +2 -2
- package/build/components/VideoRendererView.js +3 -2
- package/build/components/VideoRendererView.js.map +1 -1
- package/build/consts/index.d.ts +3 -0
- package/build/consts/index.d.ts.map +1 -0
- package/build/consts/index.js +4 -0
- package/build/consts/index.js.map +1 -0
- package/build/debug/stats/useRTCStatistics.js.map +1 -1
- package/build/hooks/useCamera.d.ts +5 -5
- package/build/hooks/useCamera.js.map +1 -1
- package/build/hooks/useConnection.d.ts +18 -7
- package/build/hooks/useConnection.d.ts.map +1 -1
- package/build/hooks/useConnection.js +10 -2
- package/build/hooks/useConnection.js.map +1 -1
- package/build/hooks/useMicrophone.d.ts +6 -2
- package/build/hooks/useMicrophone.d.ts.map +1 -1
- package/build/hooks/useMicrophone.js +12 -2
- package/build/hooks/useMicrophone.js.map +1 -1
- package/build/hooks/usePeers.js.map +1 -1
- package/build/hooks/usePermissions.d.ts +24 -0
- package/build/hooks/usePermissions.d.ts.map +1 -0
- package/build/hooks/usePermissions.js +61 -0
- package/build/hooks/usePermissions.js.map +1 -0
- package/build/hooks/useSandbox.d.ts +13 -0
- package/build/hooks/useSandbox.d.ts.map +1 -0
- package/build/hooks/useSandbox.js +42 -0
- package/build/hooks/useSandbox.js.map +1 -0
- package/build/hooks/useScreenShare.d.ts +1 -1
- package/build/hooks/useScreenShare.js.map +1 -1
- package/build/index.d.ts +5 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/types.d.ts +1 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/ios/CameraPermissionsRequester.swift +117 -0
- package/ios/RNFishjamClient.swift +31 -20
- package/ios/RNFishjamClientModule.swift +176 -119
- package/package.json +16 -11
- package/plugin/build/types.d.ts +5 -0
- package/plugin/build/withFishjamAndroid.js +16 -4
- package/plugin/build/withFishjamIos.d.ts +1 -1
- package/plugin/build/withFishjamIos.js +106 -48
|
@@ -33,16 +33,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.getSbePodfileSnippet = getSbePodfileSnippet;
|
|
37
37
|
// ios-related code was mostly copied from OneSignal expo plugin: https://github.com/OneSignal/onesignal-expo-plugin/blob/main/onesignal/withOneSignalIos.ts
|
|
38
38
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
39
39
|
const fs = __importStar(require("promise-fs"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
function getSbeTargetName(props) {
|
|
42
|
+
return (props?.ios?.broadcastExtensionTargetName ||
|
|
43
|
+
'FishjamScreenBroadcastExtension');
|
|
44
|
+
}
|
|
45
|
+
function getSbePodfileSnippet(props) {
|
|
46
|
+
const targetName = getSbeTargetName(props);
|
|
47
|
+
return `\ntarget '${targetName}' do\n pod 'FishjamCloudClient/Broadcast'\nend`;
|
|
48
|
+
}
|
|
46
49
|
const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
47
50
|
const IPHONEOS_DEPLOYMENT_TARGET = '15.1';
|
|
48
51
|
const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
@@ -50,8 +53,9 @@ const BUNDLE_IDENTIFIER_TEMPLATE_REGEX = /{{BUNDLE_IDENTIFIER}}/gm;
|
|
|
50
53
|
/**
|
|
51
54
|
* A helper function for updating a value in a file for given regex
|
|
52
55
|
*/
|
|
53
|
-
async function updateFileWithRegex(iosPath, fileName, regex, value) {
|
|
54
|
-
const
|
|
56
|
+
async function updateFileWithRegex(iosPath, fileName, regex, value, props) {
|
|
57
|
+
const targetName = getSbeTargetName(props);
|
|
58
|
+
const filePath = `${iosPath}/${targetName}/${fileName}`;
|
|
55
59
|
let file = await fs.readFile(filePath, { encoding: 'utf-8' });
|
|
56
60
|
file = file.replace(regex, value);
|
|
57
61
|
await fs.writeFile(filePath, file);
|
|
@@ -60,23 +64,24 @@ async function updateFileWithRegex(iosPath, fileName, regex, value) {
|
|
|
60
64
|
* Inserts a required target to Podfile.
|
|
61
65
|
* This is needed to provide the dependency of FishjamCloudClient/Broadcast to the extension.
|
|
62
66
|
*/
|
|
63
|
-
async function updatePodfile(iosPath) {
|
|
67
|
+
async function updatePodfile(iosPath, props) {
|
|
68
|
+
const podfileSnippet = getSbePodfileSnippet(props);
|
|
64
69
|
let matches;
|
|
65
70
|
try {
|
|
66
71
|
const podfile = await fs.readFile(`${iosPath}/Podfile`, {
|
|
67
72
|
encoding: 'utf-8',
|
|
68
73
|
});
|
|
69
|
-
matches = podfile.match(
|
|
74
|
+
matches = podfile.match(podfileSnippet);
|
|
70
75
|
}
|
|
71
76
|
catch (e) {
|
|
72
77
|
console.error('Error reading from Podfile: ', e);
|
|
73
78
|
}
|
|
74
79
|
if (matches) {
|
|
75
|
-
console.log(`${
|
|
80
|
+
console.log(`${getSbeTargetName(props)} target already added to Podfile. Skipping...`);
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
78
83
|
try {
|
|
79
|
-
fs.appendFile(`${iosPath}/Podfile`,
|
|
84
|
+
fs.appendFile(`${iosPath}/Podfile`, podfileSnippet);
|
|
80
85
|
}
|
|
81
86
|
catch (e) {
|
|
82
87
|
console.error('Error writing to Podfile: ', e);
|
|
@@ -86,30 +91,69 @@ async function updatePodfile(iosPath) {
|
|
|
86
91
|
* Adds "App Group" permission
|
|
87
92
|
* App Group allow your app and the FishjamScreenBroadcastExtension to communicate with each other.
|
|
88
93
|
*/
|
|
89
|
-
const withAppGroupPermissions = (config) => {
|
|
94
|
+
const withAppGroupPermissions = (config, props) => {
|
|
90
95
|
const APP_GROUP_KEY = 'com.apple.security.application-groups';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
const bundleIdentifier = config.ios?.bundleIdentifier || '';
|
|
97
|
+
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
98
|
+
const mainTarget = props?.ios?.mainTargetName || '';
|
|
99
|
+
config.ios ??= {};
|
|
100
|
+
config.ios.entitlements ??= {};
|
|
101
|
+
config.ios.entitlements[APP_GROUP_KEY] ??= [];
|
|
102
|
+
const entitlementsArray = config.ios.entitlements[APP_GROUP_KEY];
|
|
103
|
+
if (!entitlementsArray.includes(groupIdentifier)) {
|
|
104
|
+
entitlementsArray.push(groupIdentifier);
|
|
105
|
+
}
|
|
106
|
+
config = (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
|
|
107
|
+
const modResultsArray = newConfig.modResults[APP_GROUP_KEY] || [];
|
|
108
|
+
if (!modResultsArray.includes(groupIdentifier)) {
|
|
109
|
+
modResultsArray.push(groupIdentifier);
|
|
99
110
|
}
|
|
100
|
-
modResultsArray
|
|
111
|
+
newConfig.modResults[APP_GROUP_KEY] = modResultsArray;
|
|
101
112
|
return newConfig;
|
|
102
113
|
});
|
|
114
|
+
config = (0, config_plugins_1.withXcodeProject)(config, (props) => {
|
|
115
|
+
const xcodeProject = props.modResults;
|
|
116
|
+
const targets = xcodeProject.getFirstTarget();
|
|
117
|
+
const project = xcodeProject.getFirstProject();
|
|
118
|
+
if (!targets || !project) {
|
|
119
|
+
return props;
|
|
120
|
+
}
|
|
121
|
+
const targetUuid = targets.uuid;
|
|
122
|
+
const projectUuid = project.uuid;
|
|
123
|
+
const projectObj = xcodeProject.hash.project.objects.PBXProject[projectUuid];
|
|
124
|
+
projectObj.attributes ??= {};
|
|
125
|
+
projectObj.attributes.TargetAttributes ??= {};
|
|
126
|
+
projectObj.attributes.TargetAttributes[targetUuid] ??= {};
|
|
127
|
+
projectObj.attributes.TargetAttributes[targetUuid].SystemCapabilities ??=
|
|
128
|
+
{};
|
|
129
|
+
projectObj.attributes.TargetAttributes[targetUuid].SystemCapabilities['com.apple.ApplicationGroups.iOS'] = {
|
|
130
|
+
enabled: 1,
|
|
131
|
+
};
|
|
132
|
+
const mainTargetName = mainTarget || props.modRequest.projectName;
|
|
133
|
+
const entitlementsFilePath = `${mainTargetName}/${mainTargetName}.entitlements`;
|
|
134
|
+
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
135
|
+
Object.keys(configurations).forEach((key) => {
|
|
136
|
+
const config = configurations[key];
|
|
137
|
+
if (config.buildSettings?.PRODUCT_NAME?.includes(mainTargetName)) {
|
|
138
|
+
if (!config.buildSettings.CODE_SIGN_ENTITLEMENTS) {
|
|
139
|
+
config.buildSettings.CODE_SIGN_ENTITLEMENTS = entitlementsFilePath;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
return props;
|
|
144
|
+
});
|
|
145
|
+
return config;
|
|
103
146
|
};
|
|
104
147
|
/**
|
|
105
148
|
* Adds constants to Info.plist
|
|
106
149
|
* In other to dynamically retreive extension's bundleId and group name we need to store it in Info.plist.
|
|
107
150
|
*/
|
|
108
|
-
const withInfoPlistConstants = (config) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
|
|
151
|
+
const withInfoPlistConstants = (config, props) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
|
|
109
152
|
const bundleIdentifier = configuration.ios?.bundleIdentifier || '';
|
|
110
|
-
|
|
153
|
+
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
154
|
+
configuration.modResults['AppGroupName'] = groupIdentifier;
|
|
111
155
|
configuration.modResults['ScreenShareExtensionBundleId'] =
|
|
112
|
-
`${bundleIdentifier}.${
|
|
156
|
+
`${bundleIdentifier}.${getSbeTargetName(props)}`;
|
|
113
157
|
return configuration;
|
|
114
158
|
});
|
|
115
159
|
/**
|
|
@@ -120,14 +164,22 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
120
164
|
const appName = props.modRequest.projectName || '';
|
|
121
165
|
const iosPath = props.modRequest.platformProjectRoot;
|
|
122
166
|
const bundleIdentifier = props.ios?.bundleIdentifier;
|
|
167
|
+
const groupIdentifier = options?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
123
168
|
const xcodeProject = props.modResults;
|
|
169
|
+
const targetName = getSbeTargetName(options);
|
|
124
170
|
const pluginDir = require.resolve('@fishjam-cloud/react-native-client/package.json');
|
|
125
171
|
const extensionSourceDir = path.join(pluginDir, '../plugin/broadcastExtensionFiles/');
|
|
126
|
-
await updatePodfile(iosPath);
|
|
172
|
+
await updatePodfile(iosPath, options);
|
|
127
173
|
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
174
|
+
const templateTargetName = 'FishjamScreenBroadcastExtension';
|
|
128
175
|
const extFiles = [
|
|
129
176
|
'FishjamBroadcastSampleHandler.swift',
|
|
130
|
-
`${
|
|
177
|
+
`${templateTargetName}.entitlements`,
|
|
178
|
+
`Info.plist`,
|
|
179
|
+
];
|
|
180
|
+
const destFiles = [
|
|
181
|
+
'FishjamBroadcastSampleHandler.swift',
|
|
182
|
+
`${targetName}.entitlements`,
|
|
131
183
|
`Info.plist`,
|
|
132
184
|
];
|
|
133
185
|
await xcodeProject.parse(async function (err) {
|
|
@@ -135,28 +187,26 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
135
187
|
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
136
188
|
return;
|
|
137
189
|
}
|
|
138
|
-
if (xcodeProject.pbxTargetByName(
|
|
139
|
-
console.log(`${
|
|
190
|
+
if (xcodeProject.pbxTargetByName(targetName)) {
|
|
191
|
+
console.log(`${targetName} already exists in project. Skipping...`);
|
|
140
192
|
return;
|
|
141
193
|
}
|
|
142
194
|
try {
|
|
143
|
-
|
|
144
|
-
await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
|
|
195
|
+
await fs.mkdir(`${iosPath}/${targetName}`, { recursive: true });
|
|
145
196
|
for (let i = 0; i < extFiles.length; i++) {
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
await fs.copyFile(
|
|
197
|
+
const srcFile = `${extensionSourceDir}${extFiles[i]}`;
|
|
198
|
+
const destFile = `${iosPath}/${targetName}/${destFiles[i]}`;
|
|
199
|
+
await fs.copyFile(srcFile, destFile);
|
|
149
200
|
}
|
|
150
201
|
}
|
|
151
202
|
catch (e) {
|
|
152
203
|
console.error('Error copying extension files: ', e);
|
|
153
204
|
}
|
|
154
|
-
|
|
155
|
-
await updateFileWithRegex(iosPath,
|
|
156
|
-
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift',
|
|
157
|
-
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '');
|
|
205
|
+
await updateFileWithRegex(iosPath, `${targetName}.entitlements`, GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier, options);
|
|
206
|
+
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier, options);
|
|
207
|
+
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '', options);
|
|
158
208
|
// Create new PBXGroup for the extension
|
|
159
|
-
const extGroup = xcodeProject.addPbxGroup(extFiles,
|
|
209
|
+
const extGroup = xcodeProject.addPbxGroup(extFiles, targetName, targetName);
|
|
160
210
|
// Add the new PBXGroup to the top level group. This makes the
|
|
161
211
|
// files / folder appear in the file explorer in Xcode.
|
|
162
212
|
const groups = xcodeProject.hash.project.objects['PBXGroup'];
|
|
@@ -176,7 +226,7 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
176
226
|
projObjects['PBXTargetDependency'] || {};
|
|
177
227
|
// Add the SBE target
|
|
178
228
|
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
179
|
-
const sbeTarget = xcodeProject.addTarget(
|
|
229
|
+
const sbeTarget = xcodeProject.addTarget(targetName, 'app_extension', targetName, `${bundleIdentifier}.${targetName}`);
|
|
180
230
|
// Add build phases to the new target
|
|
181
231
|
xcodeProject.addBuildPhase(['FishjamBroadcastSampleHandler.swift'], 'PBXSourcesBuildPhase', 'Sources', sbeTarget.uuid);
|
|
182
232
|
xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', sbeTarget.uuid);
|
|
@@ -189,15 +239,14 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
189
239
|
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
190
240
|
for (const key in configurations) {
|
|
191
241
|
if (typeof configurations[key].buildSettings !== 'undefined' &&
|
|
192
|
-
configurations[key].buildSettings.PRODUCT_NAME ===
|
|
193
|
-
`"${SBE_TARGET_NAME}"`) {
|
|
242
|
+
configurations[key].buildSettings.PRODUCT_NAME === `"${targetName}"`) {
|
|
194
243
|
const buildSettingsObj = configurations[key].buildSettings;
|
|
195
244
|
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
|
|
196
245
|
options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
197
246
|
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
198
|
-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${
|
|
247
|
+
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
|
|
199
248
|
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
|
|
200
|
-
buildSettingsObj.INFOPLIST_FILE = `${
|
|
249
|
+
buildSettingsObj.INFOPLIST_FILE = `${targetName}/Info.plist`;
|
|
201
250
|
buildSettingsObj.SWIFT_VERSION = '5.0';
|
|
202
251
|
buildSettingsObj.MARKETING_VERSION = '1.0.0';
|
|
203
252
|
buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
|
|
@@ -208,21 +257,30 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
208
257
|
});
|
|
209
258
|
return props;
|
|
210
259
|
});
|
|
260
|
+
const withFishjamPictureInPicture = (config, props) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
|
|
261
|
+
if (props?.ios?.supportsPictureInPicture) {
|
|
262
|
+
const backgroundModes = new Set(configuration.modResults.UIBackgroundModes ?? []);
|
|
263
|
+
backgroundModes.add('audio');
|
|
264
|
+
configuration.modResults.UIBackgroundModes = Array.from(backgroundModes);
|
|
265
|
+
}
|
|
266
|
+
return configuration;
|
|
267
|
+
});
|
|
211
268
|
/**
|
|
212
269
|
* Applies screen sharing plugin if enabled. In order for screensharing to work, we need to copy extension files to your iOS project.
|
|
213
270
|
* Allows for dynamically changing deploymentTarget.
|
|
214
271
|
*/
|
|
215
272
|
const withFishjamIos = (config, props) => {
|
|
216
273
|
if (props?.ios?.enableScreensharing) {
|
|
217
|
-
withAppGroupPermissions(config);
|
|
218
|
-
withInfoPlistConstants(config);
|
|
219
|
-
withFishjamSBE(config, props);
|
|
274
|
+
config = withAppGroupPermissions(config, props);
|
|
275
|
+
config = withInfoPlistConstants(config, props);
|
|
276
|
+
config = withFishjamSBE(config, props);
|
|
220
277
|
}
|
|
221
|
-
(0, config_plugins_1.withPodfileProperties)(config, (configuration) => {
|
|
278
|
+
config = (0, config_plugins_1.withPodfileProperties)(config, (configuration) => {
|
|
222
279
|
configuration.modResults['ios.deploymentTarget'] =
|
|
223
280
|
props?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
224
281
|
return configuration;
|
|
225
282
|
});
|
|
283
|
+
config = withFishjamPictureInPicture(config, props);
|
|
226
284
|
return config;
|
|
227
285
|
};
|
|
228
286
|
exports.default = withFishjamIos;
|