Skip to content

Commit

Permalink
audio messages
Browse files Browse the repository at this point in the history
  • Loading branch information
tbenr committed Jul 14, 2020
1 parent 8428678 commit 7c2a4a4
Show file tree
Hide file tree
Showing 35 changed files with 1,151 additions and 19 deletions.
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />

<uses-permission android:name="android.permission.RECORD_AUDIO" />

<uses-permission android:name="com.android.vending.BILLING" />

<!-- these permissions should be removed -->
Expand Down
29 changes: 20 additions & 9 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ PODS:
- React
- react-native-shake (3.4.0):
- React
- react-native-slider (3.0.0):
- React
- react-native-splash-screen (3.2.0):
- React
- react-native-webview (10.3.1):
Expand Down Expand Up @@ -318,6 +320,8 @@ PODS:
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- ReactCommon/callinvoker (= 0.62.2)
- ReactNativeAudioToolkit (2.0.3):
- React
- ReactNativeDarkMode (0.2.2):
- React
- RNCClipboard (1.2.2):
Expand Down Expand Up @@ -354,8 +358,8 @@ PODS:
- SQLCipher/common (3.4.2)
- SQLCipher/standard (3.4.2):
- SQLCipher/common
- SSZipArchive (2.2.2)
- TOCropViewController (2.5.2)
- SSZipArchive (2.2.3)
- TOCropViewController (2.5.3)
- TouchID (4.4.1):
- React
- Yoga (1.14.0)
Expand Down Expand Up @@ -406,6 +410,7 @@ DEPENDENCIES:
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-shake (from `../node_modules/react-native-shake`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
Expand All @@ -419,6 +424,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "ReactNativeAudioToolkit (from `../node_modules/@react-native-community/audio-toolkit`)"
- ReactNativeDarkMode (from `../node_modules/react-native-dark-mode`)
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
Expand All @@ -437,11 +443,8 @@ DEPENDENCIES:
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
- boost-for-react-native
- SQLCipher
- SSZipArchive
trunk:
- boost-for-react-native
- CocoaAsyncSocket
- CocoaLibEvent
- Flipper
Expand All @@ -452,6 +455,8 @@ SPEC REPOS:
- Flipper-RSocket
- FlipperKit
- OpenSSL-Universal
- SQLCipher
- SSZipArchive
- TOCropViewController
- YogaKit

Expand Down Expand Up @@ -500,6 +505,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-safe-area-context"
react-native-shake:
:path: "../node_modules/react-native-shake"
react-native-slider:
:path: "../node_modules/@react-native-community/slider"
react-native-splash-screen:
:path: "../node_modules/react-native-splash-screen"
react-native-webview:
Expand All @@ -524,6 +531,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/Vibration"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
ReactNativeAudioToolkit:
:path: "../node_modules/@react-native-community/audio-toolkit"
ReactNativeDarkMode:
:path: "../node_modules/react-native-dark-mode"
RNCClipboard:
Expand Down Expand Up @@ -587,6 +596,7 @@ SPEC CHECKSUMS:
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
react-native-safe-area-context: 60f654e00b6cc416573f6d5dbfce3839958eb57a
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
react-native-webview: 40bbeb6d011226f34cb83f845aeb0fdf515cfc5f
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
Expand All @@ -599,6 +609,7 @@ SPEC CHECKSUMS:
React-RCTText: fae545b10cfdb3d247c36c56f61a94cfd6dba41d
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
ReactNativeDarkMode: 0178ffca3b10f6a7c9f49d6f9810232b328fa949
RNCClipboard: 8148e21ac347c51fd6cd4b683389094c216bb543
RNCMaskedView: 71fc32d971f03b7f03d6ab6b86b730c4ee64f5b6
Expand All @@ -612,12 +623,12 @@ SPEC CHECKSUMS:
RNScreens: ac02d0e4529f08ced69f5580d416f968a6ec3a1d
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990
SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23
TOCropViewController: e9da34f484aedd4e5d5a8ab230ba217cfe16c729
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 3ebccbdd559724312790e7742142d062476b698e
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

PODFILE CHECKSUM: f66349c5bfb9c21ac968307ea5a2d6c2dd4091ed

COCOAPODS: 1.9.3
COCOAPODS: 1.9.1
2 changes: 2 additions & 0 deletions ios/StatusIm/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
<string>Location access is required for some DApps to function properly.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photos access is required to give you the ability to send images.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for sending audio messages.</string>
<key>UIAppFonts</key>
<array>
<string>Inter-Bold.otf</string>
Expand Down
2 changes: 2 additions & 0 deletions ios/StatusImPR/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
<string>Location access is required for some DApps to function properly.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photos access is required to give you the ability to send images.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for sending audio messages.</string>
<key>UIAppFonts</key>
<array>
<string>Inter-Bold.otf</string>
Expand Down
2 changes: 2 additions & 0 deletions nix/deps/gradle/proj.list
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
app
react-native-background-timer
react-native-camera
react-native-community_audio-toolkit
react-native-community_cameraroll
react-native-community_clipboard
react-native-community_masked-view
react-native-community_netinfo
react-native-community_slider
react-native-config
react-native-dark-mode
react-native-dialogs
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
"app:android": "react-native run-android"
},
"dependencies": {
"@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#v2.0.3-status-v5",
"@react-native-community/cameraroll": "^1.6.1",
"@react-native-community/clipboard": "^1.2.2",
"@react-native-community/hooks": "^2.5.1",
"@react-native-community/masked-view": "^0.1.6",
"@react-native-community/netinfo": "^4.4.0",
"@react-native-community/slider": "^3.0.0",
"@react-navigation/bottom-tabs": "^5.1.1",
"@react-navigation/native": "^5.2.3",
"@react-navigation/stack": "^5.1.1",
Expand Down
Binary file added resources/images/icons/pause@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/icons/pause@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/icons/play@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/icons/play@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/icons/speech@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/icons/speech@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/ui/slider-thumb@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/ui/slider-thumb@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 123 additions & 0 deletions src/status_im/audio/core.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
(ns status-im.audio.core
(:require ["@react-native-community/audio-toolkit" :refer (Player Recorder MediaStates)]))

;; get mediastates from react module
(def PLAYING (.-PLAYING ^js MediaStates))
(def PAUSED (.-PAUSED ^js MediaStates))
(def RECORDING (.-RECORDING ^js MediaStates))
(def PREPARED (.-PREPARED ^js MediaStates))
(def IDLE (.-IDLE ^js MediaStates))
(def ERROR (.-ERROR ^js MediaStates))
(def DESTROYED (.-DESTROYED ^js MediaStates))
(def SEEKING (.-SEEKING ^js MediaStates))

(def default-recorder-options {:filename "recording.aac"
:bitrate 32000
:channels 1
:sampleRate 22050
:quality "medium" ; ios only
:meteringInterval 50})

(defn get-state [player-recorder]
(when player-recorder
(.-state ^js player-recorder)))

(defn destroy-recorder [recorder]
(when (and recorder (not= (get-state recorder) DESTROYED))
(.destroy ^js recorder)))

(defn destroy-player [player]
(when (and player (not= (get-state player) IDLE))
(.destroy ^js player)))

(defn new-recorder [options on-meter on-ended]
(let [recorder (new ^js Recorder
(:filename options)
(clj->js options))]
(when on-meter
(.on ^js recorder "meter" on-meter))
(when on-ended
(.on ^js recorder "ended" on-ended))))

(defn new-player [audio options on-ended]
(let [player (new ^js Player
audio
(clj->js options))]
(when on-ended
(.on ^js player "ended" on-ended))))

(defn prepare-player [player on-prepared on-error]
(when (and player (.-canPrepare ^js player))
(.prepare ^js player #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-prepared)))))

(defn prepare-recorder [recorder on-prepared on-error]
(when (and recorder (.-canPrepare ^js recorder))
(.prepare ^js recorder (fn [err _]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-prepared))))))

(defn start-recording [recorder on-start on-error]
(when (and recorder
(or
(.-canRecord ^js recorder)
(.-canPrepare ^js recorder)))
(.record ^js recorder #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-start)))))

(defn stop-recording [recorder on-stop on-error]
(when (and recorder (.-isRecording ^js recorder))
(.stop ^js recorder #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-stop)))))

(defn pause-recording [recorder on-pause on-error]
(when (and recorder (.-isRecording ^js recorder))
(.pause ^js recorder #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-pause)))))

(defn start-playing [player on-start on-error]
(when (and player (.-canPlay ^js player))
(.play ^js player #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-start)))))

(defn stop-playing [player on-stop on-error]
(when (and player (.-isPlaying ^js player))
(.stop ^js player #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-stop)))))

(defn get-recorder-file-path [recorder]
(when recorder
(.-fsPath ^js recorder)))

(defn get-player-duration [player]
(when (and player (.-canPlay ^js player))
(.-duration ^js player)))

(defn get-player-current-time [player]
(when (and player (.-canPlay ^js player))
(.-currentTime ^js player)))

(defn toggle-playpause-player [player on-play on-pause on-error]
(when (and player (.-canPlay ^js player))
(.playPause ^js player (fn [error pause?]
(if error
(on-error {:error (.-err error) :message (.-message error)})
(if pause?
(on-pause)
(on-play)))))))

(defn seek-player [player value on-seek on-error]
(when (and player (.-canPlay ^js player))
(.seek ^js player value #(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-seek)))))

(defn canPlay? [player]
(and player (.-canPlay ^js player)))
19 changes: 19 additions & 0 deletions src/status_im/chat/models/input.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@
:image-path (string/replace image-path #"file://" "")
:text "Update to latest version to see a nice image here!"})))))

(fx/defn send-audio-message
[cofx audio-path duration current-chat-id]
(when-not (string/blank? audio-path)
(chat.message/send-message cofx {:chat-id current-chat-id
:content-type constants/content-type-audio
:audio-path audio-path
:audio-duration-ms duration
:text "Update to latest version to listen to an audio here!"})))

(fx/defn send-sticker-message
[cofx {:keys [hash pack]} current-chat-id]
(when-not (string/blank? hash)
Expand Down Expand Up @@ -158,3 +167,13 @@
(.clear ref)
(catch :default _
(log/debug "Cannot clear the reference")))))

(fx/defn open-audio-recorder
{:events [:chat.ui/open-audio-recorder]}
[{{:keys [current-chat-id] :as db} :db}]
{:db (assoc-in db [:chat/inputs current-chat-id :audio-recorder] true)})

(fx/defn close-audio-recorder
{:events [:chat.ui/close-audio-recorder]}
[{{:keys [current-chat-id] :as db} :db}]
{:db (update-in db [:chat/inputs current-chat-id] dissoc :audio-recorder)})
1 change: 1 addition & 0 deletions src/status_im/constants.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
(def content-type-command 5)
(def content-type-system-text 6)
(def content-type-image 7)
(def content-type-audio 8)

(def message-type-one-to-one 1)
(def message-type-public-group 2)
Expand Down
3 changes: 2 additions & 1 deletion src/status_im/data_store/messages.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
:contentType :content-type
:clock :clock-value
:quotedMessage :quoted-message
:outgoingStatus :outgoing-status})
:outgoingStatus :outgoing-status
:audioDurationMs :audio-duration-ms})

(update :outgoing-status keyword)
(update :command-parameters clojure.set/rename-keys {:transactionHash :transaction-hash
Expand Down
5 changes: 5 additions & 0 deletions src/status_im/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@
{})
(chat.input/send-sticker-message sticker current-chat-id))))

(handlers/register-handler-fx
:chat/send-audio
(fn [{{:keys [current-chat-id]} :db :as cofx} [_ audio-path duration]]
(chat.input/send-audio-message cofx audio-path duration current-chat-id)))

(handlers/register-handler-fx
:chat/disable-cooldown
(fn [cofx _]
Expand Down
3 changes: 2 additions & 1 deletion src/status_im/react_native/resources.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
:theme-dark (js/require "../resources/images/ui/theme-dark.png")
:theme-light (js/require "../resources/images/ui/theme-light.png")
:theme-system (js/require "../resources/images/ui/theme-system.png")
:notifications (js/require "../resources/images/ui/notifications.png")})
:notifications (js/require "../resources/images/ui/notifications.png")
:slider-thumb (js/require "../resources/images/ui/slider-thumb.png")})

(defn get-theme-image [k]
(get ui (when (colors/dark?) (keyword (str (name k) "-dark"))) (get ui k)))
Expand Down
7 changes: 7 additions & 0 deletions src/status_im/subs.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,13 @@
(fn [[chat-id inputs]]
(get-in inputs [chat-id :input-text])))

(re-frame/reg-sub
:chats/current-chat-audio-recorder-open?
:<- [:chats/current-chat-id]
:<- [:chat/inputs]
(fn [[chat-id inputs]]
(not (nil? (get-in inputs [chat-id :audio-recorder])))))

(re-frame/reg-sub
:chats/current-chat
:<- [:chats/current-raw-chat]
Expand Down
4 changes: 4 additions & 0 deletions src/status_im/transport/message/protocol.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
response-to
ens-name
image-path
audio-path
audio-duration-ms
message-type
sticker
content-type]
Expand All @@ -22,6 +24,8 @@
:responseTo response-to
:ensName ens-name
:imagePath image-path
:audioPath audio-path
:audioDurationMs audio-duration-ms
:sticker sticker
:contentType content-type}]
:on-success
Expand Down
Loading

0 comments on commit 7c2a4a4

Please sign in to comment.