diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle index dbf899a53..f5baa1e73 100644 --- a/android/sdk/build.gradle +++ b/android/sdk/build.gradle @@ -71,6 +71,22 @@ gradle.projectsEvaluated { runBefore("processUniversal${buildNameCapitalized}Resources", currentFontTask) runBefore("process${buildNameCapitalized}Resources", currentFontTask) + def currentSoundsTask = tasks.create( + name: "copy${buildNameCapitalized}Sounds", + type: Copy) { + from("${projectDir}/../../sounds/joined.wav") + from("${projectDir}/../../sounds/left.wav") + into("${bundlePath}/assets/sounds") + } + + currentSoundsTask.dependsOn("merge${buildNameCapitalized}Resources") + currentSoundsTask.dependsOn("merge${buildNameCapitalized}Assets") + + runBefore("processArmeabi-v7a${buildNameCapitalized}Resources", currentSoundsTask) + runBefore("processX86${buildNameCapitalized}Resources", currentSoundsTask) + runBefore("processUniversal${buildNameCapitalized}Resources", currentSoundsTask) + runBefore("process${buildNameCapitalized}Resources", currentSoundsTask) + // Bundle JavaScript and React resources. // (adapted from react-native/react.gradle) // diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1ce2fd402..571d3411a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -43,10 +43,10 @@ PODS: - React/Core - React/fishhook - React/RCTBlob - - RNSound (0.10.4): + - RNSound (0.10.9): - React/Core - - RNSound/Core (= 0.10.4) - - RNSound/Core (0.10.4): + - RNSound/Core (= 0.10.9) + - RNSound/Core (0.10.9): - React/Core - RNVectorIcons (4.4.2): - React @@ -103,7 +103,7 @@ SPEC CHECKSUMS: react-native-keep-awake: 0de4bd66de0c23178107dce0c2fcc3354b2a8e94 react-native-locale-detector: d1b2c6fe5abb56e3a1efb6c2d6f308c05c4251f1 react-native-webrtc: bc044ca9530fc802e7533f247aa08fe1b6bf8dc5 - RNSound: d0818fe2435254fe30540fae48a429c5ffb72e09 + RNSound: b360b3862d3118ed1c74bb9825696b5957686ac4 RNVectorIcons: c0dbfbf6068fefa240c37b0f71bd03b45dddac44 yoga: 17521bbb0dd54a47c0b3ac43253e78cdac7488e0 diff --git a/ios/sdk/sdk.xcodeproj/project.pbxproj b/ios/sdk/sdk.xcodeproj/project.pbxproj index f8e6c5f3a..b0d098d87 100644 --- a/ios/sdk/sdk.xcodeproj/project.pbxproj +++ b/ios/sdk/sdk.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0BCA496B1EC4BBF900B793EE /* jitsi.ttf */; }; 0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0F65EECE1D95DA94561BB47E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03F2ADC957FF109849B7FCA1 /* libPods-JitsiMeet.a */; }; + 75635B0A20751D6D00F29C9F /* joined.wav in Resources */ = {isa = PBXBuildFile; fileRef = 75635B0820751D6D00F29C9F /* joined.wav */; }; + 75635B0B20751D6D00F29C9F /* left.wav in Resources */ = {isa = PBXBuildFile; fileRef = 75635B0920751D6D00F29C9F /* left.wav */; }; C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; }; C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; }; C6A3425F204EF76800E062DD /* PiPWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425C204EF76800E062DD /* PiPWindow.swift */; }; @@ -60,6 +62,8 @@ 0BD906E51EC0C00300C8C18E /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeet.h; sourceTree = ""; }; 0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 75635B0820751D6D00F29C9F /* joined.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = joined.wav; path = ../../sounds/joined.wav; sourceTree = ""; }; + 75635B0920751D6D00F29C9F /* left.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = left.wav; path = ../../sounds/left.wav; sourceTree = ""; }; 98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = ""; }; 9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = ""; }; C6245F5B2053091D0040BE68 /* image-resize@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "image-resize@2x.png"; path = "src/picture-in-picture/image-resize@2x.png"; sourceTree = ""; }; @@ -89,6 +93,8 @@ 0BCA49681EC4BBE500B793EE /* Resources */ = { isa = PBXGroup; children = ( + 75635B0820751D6D00F29C9F /* joined.wav */, + 75635B0920751D6D00F29C9F /* left.wav */, 0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */, C6245F5B2053091D0040BE68 /* image-resize@2x.png */, C6245F5C2053091D0040BE68 /* image-resize@3x.png */, @@ -252,6 +258,8 @@ 0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */, C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */, 0BC4B8691F8C03A700CE8B21 /* CallKitIcon.png in Resources */, + 75635B0B20751D6D00F29C9F /* left.wav in Resources */, + 75635B0A20751D6D00F29C9F /* joined.wav in Resources */, C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ios/sdk/src/AppInfo.m b/ios/sdk/src/AppInfo.m index 9db363894..61fc897b9 100644 --- a/ios/sdk/src/AppInfo.m +++ b/ios/sdk/src/AppInfo.m @@ -45,8 +45,11 @@ RCT_EXPORT_MODULE(); } } + NSString *sdkBundlePath = [[NSBundle bundleForClass:self.class] bundlePath]; + return @{ @"name": name, + @"sdkBundlePath": sdkBundlePath, @"version": version }; }; diff --git a/package-lock.json b/package-lock.json index 069219b1b..1959d1482 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10405,9 +10405,9 @@ "integrity": "sha1-QeDsKqfdjxLzo+6Dr51jxLZw+KE=" }, "react-native-sound": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.4.tgz", - "integrity": "sha512-V9v4CjKgv8ekQRLOJSoKA7pxJ03F4Ih3T/RfMIlMWLktz7v/O4sdJPjRBLOzZRqAnr9FWTLbSk1ZCjioXh3mjQ==" + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.9.tgz", + "integrity": "sha1-awCw9K/QF83gn7udFx3xtdW4Uag=" }, "react-native-vector-icons": { "version": "4.4.2", diff --git a/package.json b/package.json index 0d71be086..a9304efc0 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "react-native-keep-awake": "2.0.6", "react-native-locale-detector": "github:jitsi/react-native-locale-detector#cc76092fc4335488a28a9529c8b50afae2c3ecdc", "react-native-prompt": "1.0.0", - "react-native-sound": "0.10.4", + "react-native-sound": "0.10.9", "react-native-vector-icons": "4.4.2", "react-native-webrtc": "github:jitsi/react-native-webrtc#84aee6693195c5be6b6f5f794a1e52dc7913fb3b", "react-redux": "5.0.6", diff --git a/react/features/app/functions.native.js b/react/features/app/functions.native.js index a4fd215bf..a83a8fc7b 100644 --- a/react/features/app/functions.native.js +++ b/react/features/app/functions.native.js @@ -11,3 +11,13 @@ export * from './getRouteToRender'; export function getName() { return NativeModules.AppInfo.name; } + +/** + * Returns the path to the Jitsi Meet SDK bundle on iOS. On Android it will be + * undefined. + * + * @returns {string|undefined} + */ +export function getSdkBundlePath() { + return NativeModules.AppInfo.sdkBundlePath; +} diff --git a/react/features/base/media/components/native/Audio.js b/react/features/base/media/components/native/Audio.js index b2979dab3..fa2ee4109 100644 --- a/react/features/base/media/components/native/Audio.js +++ b/react/features/base/media/components/native/Audio.js @@ -44,7 +44,7 @@ export default class Audio extends AbstractAudio { this._sound = this.props.src ? new Sound( - this.props.src, + this.props.src, null, this._soundLoadedCallback.bind(this)) : null; } diff --git a/react/features/base/participants/middleware.js b/react/features/base/participants/middleware.js index 2ce0f728b..ae1732b37 100644 --- a/react/features/base/participants/middleware.js +++ b/react/features/base/participants/middleware.js @@ -34,10 +34,7 @@ import { getParticipantById, getParticipantCount } from './functions'; -import { - PARTICIPANT_JOINED_SRC, - PARTICIPANT_LEFT_SRC -} from './sounds'; +import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds'; declare var APP: Object; @@ -214,9 +211,9 @@ function _maybePlaySounds({ getState, dispatch }, action) { */ function _registerSounds({ dispatch }) { dispatch( - registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC)); + registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_FILE)); dispatch( - registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC)); + registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE)); } /** @@ -228,7 +225,7 @@ function _registerSounds({ dispatch }) { */ function _unregisterSounds({ dispatch }) { dispatch( - unregisterSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC)); + unregisterSound(PARTICIPANT_JOINED_SOUND_ID)); dispatch( - unregisterSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC)); + unregisterSound(PARTICIPANT_LEFT_SOUND_ID)); } diff --git a/react/features/base/participants/sounds.js b/react/features/base/participants/sounds.js new file mode 100644 index 000000000..9e71942ee --- /dev/null +++ b/react/features/base/participants/sounds.js @@ -0,0 +1,11 @@ +/** + * The name of the bundled sound file which will be played when new participant + * joins the conference. + */ +export const PARTICIPANT_JOINED_FILE = 'joined.wav'; + +/** + * The name of the bundled sound file which will be played when any participant + * leaves the conference. + */ +export const PARTICIPANT_LEFT_FILE = 'left.wav'; diff --git a/react/features/base/participants/sounds.native.js b/react/features/base/participants/sounds.native.js deleted file mode 100644 index 3940b9348..000000000 --- a/react/features/base/participants/sounds.native.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Points to the sound file which will be played when new participant joins - * the conference. - */ -export const PARTICIPANT_JOINED_SRC - = require('../../../../sounds/joined.wav'); - -/** - * Points to the sound file which will be played when any participant leaves - * the conference. - */ -export const PARTICIPANT_LEFT_SRC - = require('../../../../sounds/left.wav'); diff --git a/react/features/base/participants/sounds.web.js b/react/features/base/participants/sounds.web.js deleted file mode 100644 index c2eca1732..000000000 --- a/react/features/base/participants/sounds.web.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Points to the sound file which will be played when new participant joins - * the conference. - */ -export const PARTICIPANT_JOINED_SRC = 'sounds/joined.wav'; - -/** - * Points to the sound file which will be played when any participant leaves - * the conference. - */ -export const PARTICIPANT_LEFT_SRC = 'sounds/left.wav'; diff --git a/react/features/base/sounds/actions.js b/react/features/base/sounds/actions.js index 851e4d786..a0c8c696a 100644 --- a/react/features/base/sounds/actions.js +++ b/react/features/base/sounds/actions.js @@ -9,6 +9,7 @@ import { REGISTER_SOUND, UNREGISTER_SOUND } from './actionTypes'; +import { getSoundsPath } from './functions'; /** * Adds {@link AudioElement} instance to the base/sounds feature state for the @@ -81,20 +82,19 @@ export function playSound(soundId: string): Object { * * @param {string} soundId - The global identifier which identify the sound * created for given source object. - * @param {Object|string} src - Either path to an audio file or a raw object - * which specifies the audio resource that will be associated with the given - * {@code soundId}. + * @param {string} soundName - The name of bundled audio file that will be + * associated with the given {@code soundId}. * @returns {{ * type: REGISTER_SOUND, * soundId: string, - * src: (Object | string) + * src: string * }} */ -export function registerSound(soundId: string, src: Object | string): Object { +export function registerSound(soundId: string, soundName: string): Object { return { type: REGISTER_SOUND, soundId, - src + src: `${getSoundsPath()}/${soundName}` }; } diff --git a/react/features/base/sounds/functions.android.js b/react/features/base/sounds/functions.android.js new file mode 100644 index 000000000..df99d970c --- /dev/null +++ b/react/features/base/sounds/functions.android.js @@ -0,0 +1,9 @@ +/** + * Returns the location of the sounds. On Android sounds files are copied to + * the 'assets/sounds/' folder of the SDK bundle on build time. + * + * @returns {string} + */ +export function getSoundsPath() { + return 'asset:/sounds'; +} diff --git a/react/features/base/sounds/functions.ios.js b/react/features/base/sounds/functions.ios.js new file mode 100644 index 000000000..bfdb5037e --- /dev/null +++ b/react/features/base/sounds/functions.ios.js @@ -0,0 +1,12 @@ +import { getSdkBundlePath } from '../../app'; + +/** + * Returns the location of the sounds. On iOS it's the location of the SDK + * bundle on the phone. Each sound file must be added to the SDK's XCode project + * in order to be bundled correctly. + * + * @returns {string} + */ +export function getSoundsPath() { + return getSdkBundlePath(); +} diff --git a/react/features/base/sounds/functions.web.js b/react/features/base/sounds/functions.web.js new file mode 100644 index 000000000..b4dba5281 --- /dev/null +++ b/react/features/base/sounds/functions.web.js @@ -0,0 +1,9 @@ +/** + * Returns the location of the sounds. On Web it's the relative path to + * the sounds folder placed in the source root. + * + * @returns {string} + */ +export function getSoundsPath() { + return 'sounds'; +} diff --git a/react/features/chat/middleware.js b/react/features/chat/middleware.js index cfa5b923c..45964ade9 100644 --- a/react/features/chat/middleware.js +++ b/react/features/chat/middleware.js @@ -7,7 +7,7 @@ import { MiddlewareRegistry } from '../base/redux'; import { playSound, registerSound, unregisterSound } from '../base/sounds'; import { INCOMING_MSG_SOUND_ID } from './constants'; -import { INCOMING_MSG_SOUND_SRC } from './sounds'; +import { INCOMING_MSG_SOUND_FILE } from './sounds'; declare var APP: Object; @@ -24,7 +24,7 @@ MiddlewareRegistry.register(store => next => action => { // on mobile. typeof APP === 'undefined' || store.dispatch( - registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_SRC)); + registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE)); break; case APP_WILL_UNMOUNT: diff --git a/react/features/chat/sounds.web.js b/react/features/chat/sounds.web.js index 486ad14db..1b113cb50 100644 --- a/react/features/chat/sounds.web.js +++ b/react/features/chat/sounds.web.js @@ -1,6 +1,7 @@ /** - * The audio source for the incoming chat message sound. + * The name of the bundled audio file which will be played for the incoming chat + * message sound. * * @type {string} */ -export const INCOMING_MSG_SOUND_SRC = 'sounds/incomingMessage.wav'; +export const INCOMING_MSG_SOUND_FILE = 'incomingMessage.wav';