From 60e03e3decf2ca83ce0071e257db22ee3d2675a2 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Mon, 26 Feb 2018 13:37:12 -0600 Subject: [PATCH] feat: add join/leave sounds on mobile Adds base/sounds feature which allows other features to register a sound source under specified id. A new SoundsCollection component will then render corresponding HTMLAudioElement for each such sound. Once "setRef" callback is called by the HTMLAudioElement, this element will be added to the Redux store. When that happens sound can be played through the new 'playSound' action which will call play() method on the stored HTMLAudioElement instance. --- android/sdk/build.gradle | 1 + .../org/jitsi/meet/sdk/JitsiMeetView.java | 1 + android/settings.gradle | 2 + ios/Podfile | 1 + ios/Podfile.lock | 11 +- modules/UI/UI.js | 10 -- package-lock.json | 5 + package.json | 1 + react/features/app/components/AbstractApp.js | 4 +- .../base/jwt/components/CalleeInfo.js | 2 +- .../base/media/components/AbstractAudio.js | 118 ++++++------- .../base/media/components/native/Audio.js | 55 +++++- .../base/media/components/web/Audio.js | 93 +++++++++- react/features/base/participants/constants.js | 14 ++ .../features/base/participants/middleware.js | 83 ++++++++- .../base/participants/sounds.native.js | 13 ++ .../features/base/participants/sounds.web.js | 11 ++ react/features/base/sounds/actionTypes.js | 54 ++++++ react/features/base/sounds/actions.js | 118 +++++++++++++ .../base/sounds/components/SoundCollection.js | 160 ++++++++++++++++++ .../features/base/sounds/components/index.js | 1 + react/features/base/sounds/index.js | 6 + react/features/base/sounds/middleware.js | 46 +++++ react/features/base/sounds/reducer.js | 140 +++++++++++++++ react/features/base/util/uri.js | 4 +- .../filmstrip/components/Filmstrip.web.js | 8 - 26 files changed, 862 insertions(+), 100 deletions(-) create mode 100644 react/features/base/participants/sounds.native.js create mode 100644 react/features/base/participants/sounds.web.js create mode 100644 react/features/base/sounds/actionTypes.js create mode 100644 react/features/base/sounds/actions.js create mode 100644 react/features/base/sounds/components/SoundCollection.js create mode 100644 react/features/base/sounds/components/index.js create mode 100644 react/features/base/sounds/index.js create mode 100644 react/features/base/sounds/middleware.js create mode 100644 react/features/base/sounds/reducer.js diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle index d16c86feeb..2e3ddd24b4 100644 --- a/android/sdk/build.gradle +++ b/android/sdk/build.gradle @@ -29,6 +29,7 @@ dependencies { compile project(':react-native-immersive') compile project(':react-native-keep-awake') compile project(':react-native-locale-detector') + compile project(':react-native-sound') compile project(':react-native-vector-icons') compile project(':react-native-webrtc') } diff --git a/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java b/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java index 2ed2b4588b..24f9f18beb 100644 --- a/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java +++ b/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java @@ -122,6 +122,7 @@ public class JitsiMeetView extends FrameLayout { .addPackage(new com.oney.WebRTCModule.WebRTCModulePackage()) .addPackage(new com.RNFetchBlob.RNFetchBlobPackage()) .addPackage(new com.rnimmersive.RNImmersivePackage()) + .addPackage(new com.zmxv.RNSound.RNSoundPackage()) .addPackage(new ReactPackageAdapter() { @Override public List createNativeModules( diff --git a/android/settings.gradle b/android/settings.gradle index 317e6f9f11..d7ee3147d4 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -11,6 +11,8 @@ include ':react-native-keep-awake' project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android') include ':react-native-locale-detector' project(':react-native-locale-detector').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-locale-detector/android') +include ':react-native-sound' +project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android') include ':react-native-vector-icons' project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') include ':react-native-webrtc' diff --git a/ios/Podfile b/ios/Podfile index 2a29b163bc..52d289b70f 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -28,6 +28,7 @@ target 'JitsiMeet' do pod 'react-native-locale-detector', :path => '../node_modules/react-native-locale-detector' pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc' + pod 'RNSound', :path => '../node_modules/react-native-sound' pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons' end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6244d85900..03c36cf9e5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -41,6 +41,11 @@ PODS: - React/Core - React/fishhook - React/RCTBlob + - RNSound (0.10.4): + - React/Core + - RNSound/Core (= 0.10.4) + - RNSound/Core (0.10.4): + - React/Core - RNVectorIcons (4.4.2): - React - yoga (0.51.0.React) @@ -61,6 +66,7 @@ DEPENDENCIES: - React/RCTNetwork (from `../node_modules/react-native`) - React/RCTText (from `../node_modules/react-native`) - React/RCTWebSocket (from `../node_modules/react-native`) + - RNSound (from `../node_modules/react-native-sound`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) - yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -77,6 +83,8 @@ EXTERNAL SOURCES: :path: ../node_modules/react-native-locale-detector react-native-webrtc: :path: ../node_modules/react-native-webrtc + RNSound: + :path: ../node_modules/react-native-sound RNVectorIcons: :path: ../node_modules/react-native-vector-icons yoga: @@ -89,9 +97,10 @@ SPEC CHECKSUMS: react-native-keep-awake: 0de4bd66de0c23178107dce0c2fcc3354b2a8e94 react-native-locale-detector: d1b2c6fe5abb56e3a1efb6c2d6f308c05c4251f1 react-native-webrtc: bc044ca9530fc802e7533f247aa08fe1b6bf8dc5 + RNSound: d0818fe2435254fe30540fae48a429c5ffb72e09 RNVectorIcons: c0dbfbf6068fefa240c37b0f71bd03b45dddac44 yoga: 17521bbb0dd54a47c0b3ac43253e78cdac7488e0 -PODFILE CHECKSUM: fabd6b6c27f8e1849f0668db3f403bf536ac8903 +PODFILE CHECKSUM: 1e6ce4da1b385720c726f3f131a6aaf08bf9c0ba COCOAPODS: 1.4.0 diff --git a/modules/UI/UI.js b/modules/UI/UI.js index c6f5ef4b16..5b5519f5af 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -503,11 +503,6 @@ UI.addUser = function(user) { APP.store.dispatch(showParticipantJoinedNotification(displayName)); } - if (!config.startAudioMuted - || config.startAudioMuted > APP.conference.membersCount) { - UIUtil.playSoundNotification('userJoined'); - } - // Add Peer's container VideoLayout.addParticipantContainer(user); @@ -529,11 +524,6 @@ UI.removeUser = function(id, displayName) { messageHandler.participantNotification( displayName, 'notify.somebody', 'disconnected', 'notify.disconnected'); - if (!config.startAudioMuted - || config.startAudioMuted > APP.conference.membersCount) { - UIUtil.playSoundNotification('userLeft'); - } - VideoLayout.removeParticipantContainer(id); }; diff --git a/package-lock.json b/package-lock.json index 3504e546a7..42f15d9038 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9905,6 +9905,11 @@ "resolved": "https://registry.npmjs.org/react-native-prompt/-/react-native-prompt-1.0.0.tgz", "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==" + }, "react-native-vector-icons": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-4.4.2.tgz", diff --git a/package.json b/package.json index 2928f2e396..4b3d8ca881 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,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-vector-icons": "4.4.2", "react-native-webrtc": "github:jitsi/react-native-webrtc#626818af40384356617f70366133317b6a475171", "react-redux": "5.0.6", diff --git a/react/features/app/components/AbstractApp.js b/react/features/app/components/AbstractApp.js index 124fdf33cc..7ed305f96b 100644 --- a/react/features/app/components/AbstractApp.js +++ b/react/features/app/components/AbstractApp.js @@ -15,6 +15,7 @@ import { import '../../base/profile'; import { Fragment, RouteRegistry } from '../../base/react'; import { MiddlewareRegistry, ReducerRegistry } from '../../base/redux'; +import { SoundCollection } from '../../base/sounds'; import { PersistenceRegistry } from '../../base/storage'; import { toURLString } from '../../base/util'; import { OverlayContainer } from '../../overlay'; @@ -274,6 +275,7 @@ export class AbstractApp extends Component { { this._createElement(component) } + @@ -501,7 +503,7 @@ export class AbstractApp extends Component { /** * Navigates this {@code AbstractApp} to (i.e. opens) a specific URL. * - * @param {string|Object} url - The URL to navigate this {@code AbstractApp} + * @param {Object|string} url - The URL to navigate this {@code AbstractApp} * to (i.e. the URL to open). * @protected * @returns {void} diff --git a/react/features/base/jwt/components/CalleeInfo.js b/react/features/base/jwt/components/CalleeInfo.js index c55b5b252b..3fe5ee4962 100644 --- a/react/features/base/jwt/components/CalleeInfo.js +++ b/react/features/base/jwt/components/CalleeInfo.js @@ -254,7 +254,7 @@ class CalleeInfo extends Component { if (this.state.renderAudio && this.state.ringing) { return (