diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index cc5f6f072fb7..4254941dd844 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -21,6 +21,8 @@
+
+
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 91b5e4874de3..20245645f0f6 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -318,6 +318,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):
@@ -354,8 +356,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)
@@ -419,6 +421,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`)"
@@ -437,11 +440,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
@@ -452,6 +452,8 @@ SPEC REPOS:
- Flipper-RSocket
- FlipperKit
- OpenSSL-Universal
+ - SQLCipher
+ - SSZipArchive
- TOCropViewController
- YogaKit
@@ -524,6 +526,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:
@@ -599,6 +603,7 @@ SPEC CHECKSUMS:
React-RCTText: fae545b10cfdb3d247c36c56f61a94cfd6dba41d
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
+ ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
ReactNativeDarkMode: 0178ffca3b10f6a7c9f49d6f9810232b328fa949
RNCClipboard: 8148e21ac347c51fd6cd4b683389094c216bb543
RNCMaskedView: 71fc32d971f03b7f03d6ab6b86b730c4ee64f5b6
@@ -612,8 +617,8 @@ SPEC CHECKSUMS:
RNScreens: ac02d0e4529f08ced69f5580d416f968a6ec3a1d
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990
- SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23
- TOCropViewController: e9da34f484aedd4e5d5a8ab230ba217cfe16c729
+ SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
+ TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 3ebccbdd559724312790e7742142d062476b698e
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
diff --git a/mobile/js_files/package.json b/mobile/js_files/package.json
index a9b93143e138..077186466210 100644
--- a/mobile/js_files/package.json
+++ b/mobile/js_files/package.json
@@ -10,6 +10,7 @@
"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",
"@react-native-community/cameraroll": "^1.6.1",
"@react-native-community/clipboard": "^1.2.2",
"@react-native-community/hooks": "^2.5.1",
diff --git a/mobile/js_files/yarn.lock b/mobile/js_files/yarn.lock
index 6aee56001dd6..e13a841131d1 100644
--- a/mobile/js_files/yarn.lock
+++ b/mobile/js_files/yarn.lock
@@ -1207,6 +1207,14 @@
"@types/yargs" "^15.0.0"
chalk "^3.0.0"
+"@react-native-community/audio-toolkit@git+https://github.com/tbenr/react-native-audio-toolkit.git#v2.0.3-status":
+ version "2.0.3"
+ resolved "git+https://github.com/tbenr/react-native-audio-toolkit.git#df14bedfd70f0a02aaf9d1d6f0dd35ffe717299f"
+ dependencies:
+ async "^2.6.3"
+ eventemitter3 "^1.2.0"
+ lodash "^4.17.15"
+
"@react-native-community/cameraroll@^1.6.1":
version "1.6.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cameraroll/-/cameraroll-1.6.2.tgz#a4dedcf8ba7bc938f805dd07dd43a275edb1f411"
@@ -1821,7 +1829,7 @@ async-limiter@~1.0.0:
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
-async@^2.4.0:
+async@^2.4.0, async@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
@@ -3245,6 +3253,11 @@ event-target-shim@^5.0.0, event-target-shim@^5.0.1:
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
+eventemitter3@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
+ integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=
+
eventemitter3@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
diff --git a/nix/deps/gradle/deps.json b/nix/deps/gradle/deps.json
index 036f33690a18..375977b66b7e 100644
--- a/nix/deps/gradle/deps.json
+++ b/nix/deps/gradle/deps.json
@@ -5554,26 +5554,26 @@
},
{
- "path": "com/google/auto/value/auto-value-annotations/1.7.2/auto-value-annotations-1.7.2",
+ "path": "com/google/auto/value/auto-value-annotations/1.7.3/auto-value-annotations-1.7.3",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "5aef9d8912438ba9c964822687e836a8eacdff42",
- "sha256": "1v9w96cxqd9dnm1qxilizvdljzciqv24hsnbwqf1y355whmjnjfw"
+ "sha1": "fd25d76eeeec987053ac5c242476519e30204657",
+ "sha256": "0xl91j3zyxmqqmc4zj82s5xakdx6c4mz8hg9vmmxcnqbvs3l5ca4"
},
"jar": {
- "sha1": "7eec707327ec1663b9387c8671efb6808750e039",
- "sha256": "1aw54c5ch164kawqmgqjl5ndds7qav2kkckvjnhh68d1calqsfc7"
+ "sha1": "59ce5ee6aea918f674229f1147da95fdf7f31ce6",
+ "sha256": "0gg3v68ms4wf0in56il4ly22vs7zmdnpx8qqgl70kr7vyzwr7cz0"
}
},
{
- "path": "com/google/auto/value/auto-value-parent/1.7.2/auto-value-parent-1.7.2",
+ "path": "com/google/auto/value/auto-value-parent/1.7.3/auto-value-parent-1.7.3",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "c022e9c0ddc49607c8e5d68aee0c16392732eb1e",
- "sha256": "0lmh29zyz0izw1cywdk5fs155smdvxk899bw6y9l1i8vkkk8s4yp"
+ "sha1": "2fa007c7efdcab57172ef5a6327d8ec488899b23",
+ "sha256": "1bdvfmch78pvknr646757lv5z3vj0wlphjwsjh0mb9qlw99g2i6l"
}
},
@@ -5790,16 +5790,16 @@
},
{
- "path": "com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4",
+ "path": "com/google/errorprone/error_prone_annotations/2.4.0/error_prone_annotations-2.4.0",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "9a23fcb83bc8ed502506a8e6c648bf763dc5bcf9",
- "sha256": "1vavpvwnawnfhw8lcnba1zv3w6c5zc8nm1kvc37wlz2g9f5769hk"
+ "sha1": "efece50811944f4b355130bc01f5eb2739d28e58",
+ "sha256": "0ks7330dr2ys6jb0zj3pgx8aadw7mj2d4n21117kv80f4vx4p9by"
},
"jar": {
- "sha1": "dac170e4594de319655ffb62f41cbd6dbb5e601e",
- "sha256": "0b00bg90n9ni33x0mpyx4iffzrrcbyx58s0vw59nqq6fjzmddxxs"
+ "sha1": "32ecccc595e4e4d813a80ee9e3ab5813d65874eb",
+ "sha256": "0a5287bvcaaqvx6y90zn7bqnjwrxb26k1ps9w25jwrha4d40cajz"
}
},
@@ -5834,12 +5834,12 @@
},
{
- "path": "com/google/errorprone/error_prone_parent/2.3.4/error_prone_parent-2.3.4",
+ "path": "com/google/errorprone/error_prone_parent/2.4.0/error_prone_parent-2.4.0",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "a9b9dd42d174a5f96d6c195525877fc6d0b2028a",
- "sha256": "11i162j51sf2443ll9vs6j14lfcwknw59h6z1y7kklk0g91mnja0"
+ "sha1": "b9ca052d865d3ed214b61462960923998be720e8",
+ "sha256": "16l69qpwxaxk1qk18s15sadr3yykkj11rlp01p42lxfslk6s1pfy"
}
},
@@ -6182,16 +6182,16 @@
},
{
- "path": "com/google/protobuf/protobuf-java/3.12.1/protobuf-java-3.12.1",
+ "path": "com/google/protobuf/protobuf-java/3.12.2/protobuf-java-3.12.2",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "9f534fa0cea834450a87bb99ca02e36695037e2b",
- "sha256": "1hdlmkcrkh8li38zqzvjfcd2f2lvknvydnpc3rxmr0hsj6pimfsz"
+ "sha1": "da3bb9dce2a722503f0d3e4f3b5eea93f737ba48",
+ "sha256": "1ijicnm83gq33px9c5r4man0n2zw6axrxsqw0jnm1miixyjz08cv"
},
"jar": {
- "sha1": "48e4a0c3bf6750e6c4efa40a9f13defa869a2f57",
- "sha256": "0b55fvlykjf14r01z4aymlrw4a35jklkkpvwm1zmyjybhz7mbq7w"
+ "sha1": "f0029524002295154c6b546d4e6bd1cfc5081874",
+ "sha256": "186a1lgmcfr3iml7bfxk9gnbsafyxmriqfyglvkwa85d7gwvx1dk"
}
},
@@ -6216,12 +6216,12 @@
},
{
- "path": "com/google/protobuf/protobuf-parent/3.12.1/protobuf-parent-3.12.1",
+ "path": "com/google/protobuf/protobuf-parent/3.12.2/protobuf-parent-3.12.2",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "63dbda33bf785fe89f47c99c18a7a68688794276",
- "sha256": "1d7dsw32p6s69ffn7py229ndg6qrf0hrw6y6cxxjyq9xczf42338"
+ "sha1": "f5b5d4cb5e6d512f2fac5d2b08e599644a53c087",
+ "sha256": "0md51xi5af8yi9l1dpqbmysrvlll05zpvmalag6p4f6fykwcry05"
}
},
@@ -6420,16 +6420,16 @@
},
{
- "path": "com/squareup/okio/okio/2.7.0-alpha.lockfree.1/okio-2.7.0-alpha.lockfree.1",
+ "path": "com/squareup/okio/okio/2.7.0-alpha.lockfree.2/okio-2.7.0-alpha.lockfree.2",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "93f841606965109787a468e49a38c3e1031599e0",
- "sha256": "1nnjv05r7x044ryh0dnsvib6220wqjbbxv3xxq68qjvq22yzq2nn"
+ "sha1": "c3e3eca5d192679ca91729b81992f0564e964b68",
+ "sha256": "11bp2yxj5k04cxrjamf1pbxkm1ghhv83z47f0blgl05mwgd1xpl0"
},
"jar": {
- "sha1": "a025f03782f6c1aec46c151da0c0add297010f61",
- "sha256": "0s7k48i95qqpqixs46xibzd7gw74d1a74m5m4939crjwjz4gkn86"
+ "sha1": "1b89666c085f2f7bbcc02e90b9f3b7e035314218",
+ "sha256": "06bimqyial008vxfn32bw3d4hx3d65022v6ahgvb78ipij2a3im9"
}
},
@@ -6540,12 +6540,12 @@
},
{
- "path": "com/sun/xml/bind/jaxb-bom-ext/3.0.0-M3/jaxb-bom-ext-3.0.0-M3",
+ "path": "com/sun/xml/bind/jaxb-bom-ext/3.0.0-M4/jaxb-bom-ext-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "87660d0b2d3e743e8768ca35067798087429b69e",
- "sha256": "0j4d162d4dmafi36pnx453k6sifrczjra52rnyyyqnm08ilv1df3"
+ "sha1": "f6b46b0e806dac58917a43223782b2aed39ea652",
+ "sha256": "1cnjk3dxw3qk8sp716qklk6jcfbg5ryg6fqgfgah180pll9slldq"
}
},
@@ -6560,12 +6560,12 @@
},
{
- "path": "com/sun/xml/bind/mvn/jaxb-parent/3.0.0-M3/jaxb-parent-3.0.0-M3",
+ "path": "com/sun/xml/bind/mvn/jaxb-parent/3.0.0-M4/jaxb-parent-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "6f7a9a57584c760ade0ea1254867799389dc5ea9",
- "sha256": "0gakrwa5yzhgaz26sj6h0lfiwgbd9cjfxh2zznlqh1jq2ak7kyhh"
+ "sha1": "1bacfd08abc2072018ec7c78e34cca867cea5548",
+ "sha256": "03k0i5wgizmx5r0f53djlfw7i9plb28qas796mr8vnp2rjy51a13"
}
},
@@ -6590,12 +6590,12 @@
},
{
- "path": "com/sun/xml/bind/mvn/jaxb-txw-parent/3.0.0-M3/jaxb-txw-parent-3.0.0-M3",
+ "path": "com/sun/xml/bind/mvn/jaxb-txw-parent/3.0.0-M4/jaxb-txw-parent-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "c43f6d76e67507998c870bea97a4fb57b3dee903",
- "sha256": "1lshn5izj3zp25whyv43dbinm73kf5lx64kkhvnkfvqjm0mmdlq4"
+ "sha1": "a796032f4a0117ba47401b9e3233df8d1779c0f3",
+ "sha256": "161nir0qk32pz7jnd8ljz9d37qbg28x20jfbwx6nhpk4n3492fkq"
}
},
@@ -8002,16 +8002,16 @@
},
{
- "path": "org/checkerframework/checker-qual/3.4.0/checker-qual-3.4.0",
+ "path": "org/checkerframework/checker-qual/3.4.1/checker-qual-3.4.1",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "ec1663cd82fd24839d5eb2b5de8dd9dca47b3f78",
- "sha256": "0cs0vn3ka4vkn21c84lwv7kfqblq14kq4my1c9zavq71k5vvwibd"
+ "sha1": "48f9d7fe1e9df19b41d95388fed313dacddcea69",
+ "sha256": "0x4k1glx55qppc9cnri07va54fd20wg3hmgvj4s7rdrgjg8c0wc1"
},
"jar": {
- "sha1": "36830784bdefda6dcf8fc217e0416d8291bfe7fa",
- "sha256": "1hjsmh708hym8b2kvkfcv5hbk7j746gf5f1926wr26vaq0p90aia"
+ "sha1": "b3df2bf4d7d258e5aa192c3ac6f7f84688046262",
+ "sha256": "0zjha61sasdfyscmll51cjcnzxgqzqcmkq7w1yfdchh58s3wirdw"
}
},
@@ -8280,12 +8280,12 @@
},
{
- "path": "org/glassfish/jaxb/jaxb-bom/3.0.0-M3/jaxb-bom-3.0.0-M3",
+ "path": "org/glassfish/jaxb/jaxb-bom/3.0.0-M4/jaxb-bom-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
- "sha1": "4599efca8af86d90de8505c3f9f561e748cdf680",
- "sha256": "1qfhsc7gz7w1xpkwfbli9yzm31vln3m5wxhwrg70l91f76i1sr3b"
+ "sha1": "eaa73c4a5fba23d9f3da8e95428bec55a722eabf",
+ "sha256": "1vqn88lq4x0y1n8h669myg5h6laizr53jwngmhjb1lipxz6gxcpl"
}
},
@@ -8304,16 +8304,16 @@
},
{
- "path": "org/glassfish/jaxb/jaxb-core/3.0.0-M3/jaxb-core-3.0.0-M3",
+ "path": "org/glassfish/jaxb/jaxb-core/3.0.0-M4/jaxb-core-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "7bfd3d071e95e2a1ac7d76a717d5a0140bd2fc9f",
- "sha256": "1j1dbbdsrgd2y8nxayrb18p2k7g89pwk54jbplhyy18px0h1gjaw"
+ "sha1": "e669c8c7c0cd75d3201ee3538588f7304b8dac8b",
+ "sha256": "0h8mvvbj743vvmyrvwmqpsf7qc1fl1l6vq19mwxpmvs0pisp0y9y"
},
"jar": {
- "sha1": "b40a6d72c0c8aea8538f58f8f1a370dde74991d3",
- "sha256": "0ag58wfvg0gwqg0rxyqj1j8siymz5nqaqpcpkx95nn5n6d1wzn5y"
+ "sha1": "47d4d84d0861122c71a4cdf71fc6c0b66d4a13f1",
+ "sha256": "193bkzs93cz6zl3n7q8qy1n9c9bm5lkcrmg66sbb3qk1rlrnw485"
}
},
@@ -8346,16 +8346,16 @@
},
{
- "path": "org/glassfish/jaxb/txw2/3.0.0-M3/txw2-3.0.0-M3",
+ "path": "org/glassfish/jaxb/txw2/3.0.0-M4/txw2-3.0.0-M4",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
- "sha1": "3515e65f22e70651ec40652995d58d4639ab282f",
- "sha256": "0n4zril9pk56a8jwaxpjhw44kdjmadnavz3dmds7g0hgmyblgrb0"
+ "sha1": "b5633883ac1e877537f805434c63254ee148d5c9",
+ "sha256": "0yvarhya3dxa3mhxv8cvrk1phnpa6l65grfanrvmj7ix160w1ilf"
},
"jar": {
- "sha1": "402cd8ef4b6fb5b659da98dbf58647b97815b31e",
- "sha256": "1ybrhsjacr13dp8g9b1hrl6rpn4p277vinzr1vmyv1fhf2ikgac8"
+ "sha1": "fef146e275c3f85b82977848df2573bcfe168b3b",
+ "sha256": "19a2q7cg16a093v337l7iyf7yl3rx87b8rvl0ynwhpmgvxd6qr2k"
}
},
diff --git a/nix/deps/gradle/deps.urls b/nix/deps/gradle/deps.urls
index 04f577153749..15a6ecab7c6d 100644
--- a/nix/deps/gradle/deps.urls
+++ b/nix/deps/gradle/deps.urls
@@ -395,8 +395,8 @@ https://repo.maven.apache.org/maven2/com/googlecode/java-diff-utils/diffutils/1.
https://repo.maven.apache.org/maven2/com/googlecode/json-simple/json-simple/1.1/json-simple-1.1.pom
https://repo.maven.apache.org/maven2/com/googlecode/juniversalchardet/juniversalchardet/1.0.3/juniversalchardet-1.0.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/3/auto-parent-3.pom
-https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.7.2/auto-value-annotations-1.7.2.pom
-https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.7.2/auto-value-parent-1.7.2.pom
+https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.7.3/auto-value-annotations-1.7.3.pom
+https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.7.3/auto-value-parent-1.7.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.pom
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.pom
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/2.0.1/jsr305-2.0.1.pom
@@ -413,11 +413,11 @@ https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.5/gson-2.8.5.
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.2.0/error_prone_annotations-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.3.1/error_prone_annotations-2.3.1.pom
-https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.pom
+https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.4.0/error_prone_annotations-2.4.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1.pom
-https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.4/error_prone_parent-2.3.4.pom
+https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.4.0/error_prone_parent-2.4.0.pom
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom
@@ -445,10 +445,10 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java-util/3.4.
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/2.5.0/protobuf-java-2.5.0.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.0.0/protobuf-java-3.0.0.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.4.0/protobuf-java-3.4.0.pom
-https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.12.1/protobuf-java-3.12.1.pom
+https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.12.2/protobuf-java-3.12.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.0.0/protobuf-parent-3.0.0.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.4.0/protobuf-parent-3.4.0.pom
-https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.12.1/protobuf-parent-3.12.1.pom
+https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.12.2/protobuf-parent-3.12.2.pom
https://repo.maven.apache.org/maven2/com/google/truth/truth-parent/1.0.1/truth-parent-1.0.1.pom
https://repo.maven.apache.org/maven2/com/google/truth/truth/1.0.1/truth-1.0.1.pom
https://repo.maven.apache.org/maven2/com/google/zxing/core/3.3.3/core-3.3.3.pom
@@ -464,7 +464,7 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.6.0/okio-2.6.0.pom
-https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.7.0-alpha.lockfree.1/okio-2.7.0-alpha.lockfree.1.pom
+https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.7.0-alpha.lockfree.2/okio-2.7.0-alpha.lockfree.2.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/2.0.0-RC3/all-2.0.0-RC3.pom
https://repo.maven.apache.org/maven2/com/sun/activation/jakarta.activation/2.0.0-RC3/jakarta.activation-2.0.0-RC3.pom
@@ -474,12 +474,12 @@ https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons-runtime/4.0.0
https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons/2.21/istack-commons-2.21.pom
https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons/4.0.0-M3/istack-commons-4.0.0-M3.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/2.2.11/jaxb-bom-ext-2.2.11.pom
-https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/3.0.0-M3/jaxb-bom-ext-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/3.0.0-M4/jaxb-bom-ext-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/2.2.11/jaxb-parent-2.2.11.pom
-https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/3.0.0-M3/jaxb-parent-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/3.0.0-M4/jaxb-parent-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-runtime-parent/2.2.11/jaxb-runtime-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/2.2.11/jaxb-txw-parent-2.2.11.pom
-https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/3.0.0-M3/jaxb-txw-parent-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/3.0.0-M4/jaxb-txw-parent-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.13/FastInfoset-1.2.13.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/2.0.0-M2/FastInfoset-2.0.0-M2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/fastinfoset-project/1.2.13/fastinfoset-project-1.2.13.pom
@@ -595,7 +595,7 @@ https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.56/bcprov
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.60/bcprov-jdk15on-1.60.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.pom
-https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.4.0/checker-qual-3.4.0.pom
+https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.4.1/checker-qual-3.4.1.pom
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-all/2.4.15/groovy-all-2.4.15.pom
https://repo.maven.apache.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.pom
@@ -618,12 +618,12 @@ https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.4/ecj-4
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.5.1/ecj-4.5.1.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.6.1/ecj-4.6.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/2.2.11/jaxb-bom-2.2.11.pom
-https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/3.0.0-M3/jaxb-bom-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/3.0.0-M4/jaxb-bom-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/2.2.11/jaxb-core-2.2.11.pom
-https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/3.0.0-M3/jaxb-core-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/3.0.0-M4/jaxb-core-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.2.11/jaxb-runtime-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/2.2.11/txw2-2.2.11.pom
-https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/3.0.0-M3/txw2-3.0.0-M3.pom
+https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/3.0.0-M4/txw2-3.0.0-M4.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-core-2.2.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
diff --git a/nix/deps/gradle/proj.list b/nix/deps/gradle/proj.list
index 8b3dde7b6b65..2ae73c9bb7ed 100644
--- a/nix/deps/gradle/proj.list
+++ b/nix/deps/gradle/proj.list
@@ -1,6 +1,7 @@
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
diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs
index 56eb62a89c6c..4719e1df6a2e 100644
--- a/src/status_im/chat/models/input.cljs
+++ b/src/status_im/chat/models/input.cljs
@@ -126,6 +126,14 @@
: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 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
+ :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)
diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs
index 9ff808aa087a..fab0c1d06594 100644
--- a/src/status_im/constants.cljs
+++ b/src/status_im/constants.cljs
@@ -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)
diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs
index a14ec8d98117..cfd30b0b504b 100644
--- a/src/status_im/events.cljs
+++ b/src/status_im/events.cljs
@@ -575,6 +575,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]]
+ (chat.input/send-audio-message cofx audio-path current-chat-id)))
+
(handlers/register-handler-fx
:chat/disable-cooldown
(fn [cofx _]
diff --git a/src/status_im/transport/message/protocol.cljs b/src/status_im/transport/message/protocol.cljs
index eb5a5c697750..233178f4b0a9 100644
--- a/src/status_im/transport/message/protocol.cljs
+++ b/src/status_im/transport/message/protocol.cljs
@@ -10,6 +10,7 @@
response-to
ens-name
image-path
+ audio-path
message-type
sticker
content-type]
@@ -22,6 +23,7 @@
:responseTo response-to
:ensName ens-name
:imagePath image-path
+ :audioPath audio-path
:sticker sticker
:contentType content-type}]
:on-success
diff --git a/src/status_im/ui/components/permissions.cljs b/src/status_im/ui/components/permissions.cljs
index cb85e584018c..74ce8bc21933 100644
--- a/src/status_im/ui/components/permissions.cljs
+++ b/src/status_im/ui/components/permissions.cljs
@@ -5,7 +5,8 @@
(def permissions-map
{:read-external-storage "android.permission.READ_EXTERNAL_STORAGE"
:write-external-storage "android.permission.WRITE_EXTERNAL_STORAGE"
- :camera "android.permission.CAMERA"})
+ :camera "android.permission.CAMERA"
+ :record-audio "android.permission.RECORD_AUDIO"})
(defn all-granted? [permissions]
(let [permission-vals (distinct (vals permissions))]
diff --git a/src/status_im/ui/screens/chat/audio_message/views.cljs b/src/status_im/ui/screens/chat/audio_message/views.cljs
new file mode 100644
index 000000000000..9c24bac28895
--- /dev/null
+++ b/src/status_im/ui/screens/chat/audio_message/views.cljs
@@ -0,0 +1,364 @@
+(ns status-im.ui.screens.chat.audio-message.views
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
+ (:require [clojure.string :as string]
+ [reagent.core :as reagent]
+ [status-im.ui.components.react :as react]
+ [status-im.utils.platform :as platform]
+ [re-frame.core :as re-frame]
+ [status-im.i18n :as i18n]
+ [status-im.ui.components.button :as button]
+ [status-im.ui.components.colors :as colors]
+ [status-im.ui.components.animation :as anim]
+ [status-im.ui.components.icons.vector-icons :as icons]
+ [status-im.utils.utils :as utils.utils]
+ [status-im.utils.fs :as fs]
+ ["@react-native-community/audio-toolkit" :refer (Player Recorder MediaStates)]))
+
+;; get mediastates from react module
+(defonce PLAYING (.-PLAYING ^js MediaStates))
+(defonce PAUSED (.-PAUSED ^js MediaStates))
+(defonce RECORDING (.-RECORDING ^js MediaStates))
+(defonce PREPARED (.-PREPARED ^js MediaStates))
+(defonce IDLE (.-IDLE ^js MediaStates))
+(defonce ERROR (.-ERROR ^js MediaStates))
+(defonce DESTROYED (.-DESTROYED ^js MediaStates))
+
+;; panel management
+(defn- request-record-audio-permissions []
+ (re-frame/dispatch
+ [:request-permissions
+ {:permissions [:record-audio]
+ :on-allowed
+ #(re-frame/dispatch [:chat.ui/set-chat-ui-props
+ {:input-bottom-sheet :audio-message}])
+ :on-denied
+ #(utils.utils/set-timeout
+ (fn []
+ (utils.utils/show-popup (i18n/label :t/error)
+ (i18n/label "you have to give permission to send audio messages")))
+ 50)}]))
+
+(defn input-button [audio-message-showing?]
+ [react/touchable-highlight
+ {:on-press
+ (fn [_]
+ (if audio-message-showing?
+ (re-frame/dispatch [:chat.ui/set-chat-ui-props
+ {:input-bottom-sheet nil}])
+ (request-record-audio-permissions))
+ (when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
+ :accessibility-label :show-audio-message-icon}
+ [icons/icon
+ :main-icons/warning
+ {:container-style {:margin 14 :margin-right 6}
+ :color (if audio-message-showing? colors/blue colors/gray)}]])
+
+(defn show-panel-anim
+ [bottom-anim-value alpha-value]
+ (anim/start
+ (anim/parallel
+ [(anim/spring bottom-anim-value {:toValue 0
+ :useNativeDriver true})
+ (anim/timing alpha-value {:toValue 1
+ :duration 500
+ :useNativeDriver true})])))
+
+;; --- AUDIO stuff
+
+(def base-filename "am.")
+
+(defonce recorder-ref (atom nil))
+(defonce player-ref (atom nil))
+(def default-rec-options {:filename (str base-filename "aac")
+ :bitrate 32000
+ :channels 1
+ :sampleRate 22050
+ :quality "medium" ; ios only
+ :meteringInterval 50})
+
+(defonce state-cb (atom #()))
+(defonce record-ended-cb (atom #()))
+(defonce meter-cb (atom #()))
+
+(defn destroy-recorder []
+ (when @recorder-ref
+ (when (not= (.-state ^js @recorder-ref) DESTROYED)
+ (.destroy ^js @recorder-ref))
+ (reset! recorder-ref nil)))
+
+(defn destroy-player []
+ (when @player-ref
+ (when (not= (.-state ^js @player-ref) DESTROYED)
+ (.destroy ^js @player-ref))
+ (reset! player-ref nil)))
+
+(defn reload-recorder [options-ref]
+ (print "initializing recorder with: " @options-ref)
+ (when @recorder-ref
+ (destroy-recorder))
+ (reset! recorder-ref
+ (new ^js Recorder
+ (:filename @options-ref)
+ (clj->js @options-ref)))
+ ;(.prepare ^js @recorder-ref state-cb) ;; if a recorder is prepared, player wont play
+ (@state-cb)
+ (.on ^js @recorder-ref "meter" @meter-cb)
+ (.on ^js @recorder-ref "ended" @state-cb))
+
+(defn reload-player [options-ref]
+ (when @player-ref
+ (destroy-player))
+ (reset! player-ref
+ (new ^js Player
+ (:filename @options-ref)
+ (clj->js {:autoDestroy false})))
+ (.prepare ^js @player-ref #(if %
+ (utils.utils/show-popup (str "prepare " (.-err %)) (.-message %))
+ (@state-cb)))
+ (.on ^js @player-ref "ended" @state-cb))
+
+(defn start-recording []
+ (when @recorder-ref
+ (.record ^js @recorder-ref #(if %
+ (utils.utils/show-popup (.-err %) (.-message %))
+ (@state-cb)))))
+
+(defn start-playing []
+ (when @player-ref
+ (.play ^js @player-ref #(if %
+ (utils.utils/show-popup (.-err %) (.-message %))
+ (@state-cb)))))
+
+(defn stop-recording [options-ref]
+ (when @recorder-ref
+ (.stop ^js @recorder-ref #(if %
+ (utils.utils/show-popup (.-err %) (.-message %))
+ (do
+ (reload-recorder options-ref)
+ (reload-player options-ref))))))
+
+(defn stop-playing []
+ (when @player-ref
+ (.stop ^js @player-ref #(if %
+ (utils.utils/show-popup (.-err %) (.-message %))
+ (@state-cb)))))
+
+(defn update-options [new-option options-ref]
+ (reset! options-ref (merge @options-ref new-option)))
+
+;; -- UI stuff
+
+(defn update-info [state-ref info error]
+ (if info
+ (let [size (int (.-size info))
+ b64s (* size 1.33)
+ b64kb (quot b64s 1024)
+ duration (:duration @state-ref)
+ s (when (and duration (not= duration -1))
+ (utils.utils/format-decimals (/ duration 1000) 1))
+ ratio (when (and duration (not= duration -1))
+ (utils.utils/format-decimals (/ (/ b64s 1024) (/ duration 1000)) 2))
+ msg (str s "s --- b64 size: " b64kb "kb --- kb/s: " ratio "kb")]
+ (reset! state-ref (merge @state-ref {:info msg})))
+ (utils.utils/show-popup "fileinfo error" error)))
+
+;; general state
+;; - :recording
+;; - :playing
+;; - :ready-to-send
+;; - :ready-to-record
+(defn update-state [state-ref]
+ (let [player-state (when @player-ref (.-state ^js @player-ref))
+ recorder-state (when @recorder-ref (.-state ^js @recorder-ref))
+ output-file (or
+ (when @recorder-ref
+ (.-fsPath ^js @recorder-ref))
+ (:output-file @state-ref))
+ general (cond
+ (= recorder-state RECORDING) :recording
+ (= player-state PLAYING) :playing
+ (= player-state PREPARED) :ready-to-send
+ :else :ready-to-record)
+ new-state {:general general
+ :working? (or
+ (= general :recording)
+ (= general :playing))
+ :output-file output-file
+ :duration (when (= player-state PREPARED)
+ (.-duration ^js @player-ref))
+ :info (if (= general :recording)
+ "-recording-"
+ (:info @state-ref))}]
+ (when (and output-file (not= general :recording))
+ (fs/stat output-file
+ #(update-info state-ref % nil)
+ #(update-info state-ref nil %)))
+ (when (not= @state-ref new-state)
+ (print "oldstate" @state-ref "newstate" new-state)
+ (reset! state-ref new-state))))
+
+(defn update-meter [meter-data meter-ref]
+ (reset! meter-ref (str (int (.-value ^js meter-data)) "db")))
+
+(def options-btn-cont-style {:height 30 :margin-horizontal 4 :padding-horizontal 12})
+(def options-cont-style {:flex 1
+ :flex-direction :row
+ :align-items :center
+ :justify-content :center
+ :margin-top 0})
+
+(defview audio-message-view []
+ (letsubs [panel-height [:chats/chat-panel-height]
+ bottom-anim-value (anim/create-value @panel-height)
+ alpha-value (anim/create-value 0)
+ state (reagent/atom nil)
+ meter (reagent/atom "?db")
+ rec-options (reagent/atom default-rec-options)]
+ {:component-did-mount (fn []
+ (show-panel-anim bottom-anim-value alpha-value)
+ (reset! state-cb #(update-state state))
+ (reset! record-ended-cb #(reload-player rec-options))
+ (reset! meter-cb #(update-meter % meter))
+ (reload-recorder rec-options)
+ (add-watch rec-options :watch (fn [] (reload-recorder rec-options))))
+ :component-will-unmount (fn []
+ (destroy-recorder)
+ (destroy-player)
+ (remove-watch rec-options :watch))}
+ [react/animated-view {:style {:background-color colors/white
+ :height panel-height
+ :transform [{:translateY bottom-anim-value}]
+ :opacity alpha-value}}
+ [react/view {:style {:flex 1
+ :flex-direction :column
+ :align-items :center
+ :justify-content :center}}
+
+ ;; options - extension\encoder
+ [react/view {:style options-cont-style}
+
+ [button/button {:label "mp4"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (string/ends-with? (:filename @rec-options) "mp4"))
+ :on-press #(update-options {:filename (str base-filename "mp4")} rec-options)}]
+ [button/button {:label "aac"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (string/ends-with? (:filename @rec-options) "aac"))
+ :on-press #(update-options {:filename (str base-filename "aac")} rec-options)}]
+ [button/button {:label "ogg"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (string/ends-with? (:filename @rec-options) "ogg"))
+ :on-press #(update-options {:filename (str base-filename "ogg")} rec-options)}]
+ [button/button {:label "webm"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (string/ends-with? (:filename @rec-options) "webm"))
+ :on-press #(update-options {:filename (str base-filename "webm")} rec-options)}]
+ [button/button {:label "amr"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (string/ends-with? (:filename @rec-options) "amr"))
+ :on-press #(update-options {:filename (str base-filename "amr")} rec-options)}]]
+
+ ;; options - samplerate
+ [react/view {:style options-cont-style}
+ [button/button {:label "22kHz"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:sampleRate @rec-options) 22050))
+ :on-press #(update-options {:sampleRate 22050} rec-options)}]
+ [button/button {:label "32kHz"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:sampleRate @rec-options) 32000))
+ :on-press #(update-options {:sampleRate 32000} rec-options)}]
+ [button/button {:label "44kHz"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:sampleRate @rec-options) 44100))
+ :on-press #(update-options {:sampleRate 44100} rec-options)}]]
+
+
+ ;; options - bitrate
+
+
+ [react/view {:style options-cont-style}
+ [button/button {:label "32kbs"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:bitrate @rec-options) 32000))
+ :on-press #(update-options {:bitrate 32000} rec-options)}]
+ [button/button {:label "48kbs"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:bitrate @rec-options) 48000))
+ :on-press #(update-options {:bitrate 48000} rec-options)}]
+ [button/button {:label "64kbs"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:bitrate @rec-options) 64000))
+ :on-press #(update-options {:bitrate 64000} rec-options)}]
+ [button/button {:label "96kbs"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:bitrate @rec-options) 96000))
+ :on-press #(update-options {:bitrate 96000} rec-options)}]
+ [button/button {:label "128kbs"
+ :container-style options-btn-cont-style
+ :disabled? (if (:working? @state)
+ true
+ (= (:bitrate @rec-options) 128000))
+ :on-press #(update-options {:bitrate 128000} rec-options)}]]
+
+
+ ;; controls
+
+
+ [react/text {:style {:typography :main-medium}} (:info @state)]
+ [react/view {:style {:flex 1
+ :flex-direction :row
+ :align-items :center
+ :justify-content :center
+ :margin-top 20}}
+ [button/button {:label (if (= (:general @state) :recording)
+ "stop"
+ "rec")
+ :disabled? (= (:general @state) :playing)
+ :theme :red
+ :on-press (if (= (:general @state) :recording)
+ #(stop-recording rec-options)
+ start-recording)}]
+ [button/button {:label (if (= (:general @state) :playing)
+ "stop"
+ "play")
+ :disabled? (let [g (:general @state)]
+ (or
+ (= g :recording)
+ (= g :ready-to-record)))
+ :theme :green
+ :on-press (if (= (:general @state) :playing)
+ stop-playing
+ start-playing)}]
+ [button/button {:label "send msg"
+ :disabled? (or
+ (:working? @state)
+ (not= (:general @state) :ready-to-send)
+ (string/blank? (:output-file @state)))
+ :on-press #(re-frame/dispatch [:chat/send-audio (:output-file @state)])}]]
+ ;; metering
+ [react/text {:style {:typography :main-medium :margin-top 20}} @meter]]]))
\ No newline at end of file
diff --git a/src/status_im/ui/screens/chat/input/input.cljs b/src/status_im/ui/screens/chat/input/input.cljs
index 8c8e7ccf065a..fc071954743c 100644
--- a/src/status_im/ui/screens/chat/input/input.cljs
+++ b/src/status_im/ui/screens/chat/input/input.cljs
@@ -12,6 +12,7 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.utils.config :as config]
+ [status-im.ui.screens.chat.audio-message.views :as audio-message]
[status-im.ui.screens.chat.image.views :as image]
[status-im.ui.screens.chat.stickers.views :as stickers]
[status-im.ui.screens.chat.extensions.views :as extensions]))
@@ -90,6 +91,8 @@
[send-image-view sending-image])
[react/view {:style style/input-container}
[basic-text-input input-text cooldown-enabled?]
+ (when (and input-text-empty? (not reply-message) (not public?))
+ [audio-message/input-button (= :audio-message input-bottom-sheet)])
(when (and input-text-empty? (not reply-message) (not public?))
[image/input-button (= :images input-bottom-sheet)])
(when (and input-text-empty? mainnet? (not reply-message))
diff --git a/src/status_im/ui/screens/chat/message/audio.cljs b/src/status_im/ui/screens/chat/message/audio.cljs
new file mode 100644
index 000000000000..e99fa9379406
--- /dev/null
+++ b/src/status_im/ui/screens/chat/message/audio.cljs
@@ -0,0 +1,82 @@
+(ns status-im.ui.screens.chat.message.audio
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
+ (:require [reagent.core :as reagent]
+ [status-im.ui.components.react :as react]
+ [status-im.ui.components.button :as button]
+ ["@react-native-community/audio-toolkit" :refer (Player MediaStates)]))
+
+(defn message-press-handlers [{:keys [content] :as message}]
+ ;;TBI
+ )
+
+(defonce DESTROYED (.-DESTROYED ^js MediaStates))
+(defonce PLAYING (.-PLAYING ^js MediaStates))
+(defonce PAUSED (.-PAUSED ^js MediaStates))
+(defonce RECORDING (.-RECORDING ^js MediaStates))
+(defonce PREPARED (.-PREPARED ^js MediaStates))
+
+(defn update-state [state-ref player-ref error]
+ (let [player-state (when @player-ref (.-state ^js @player-ref))
+ general (cond
+ (some? error) :error
+ (= player-state PLAYING) :playing
+ (= player-state PAUSED) :paused
+ (= player-state PREPARED) :ready-to-play
+ :else :preparing)
+ new-state {:general general
+ :error-msg error
+ :duration (when (= player-state PREPARED)
+ (.-duration ^js @player-ref))}]
+ (when (not= @state-ref new-state)
+ (print "oldstate" @state-ref "newstate" new-state)
+ (reset! state-ref new-state))))
+
+(defn destroy-player [player-ref]
+ (when @player-ref
+ (when (not= (.-state ^js @player-ref) DESTROYED)
+ (.destroy ^js @player-ref))
+ (reset! player-ref nil)))
+
+(defn reload-player [player-ref base64-data state-ref]
+ (when @player-ref
+ (destroy-player player-ref))
+ (reset! player-ref
+ (new ^js Player
+ base64-data
+ (clj->js {:autoDestroy false})))
+ (.prepare ^js @player-ref #(if %
+ (update-state state-ref player-ref (.-message %))
+ (update-state state-ref player-ref nil)))
+ (.on ^js @player-ref "ended" #(update-state state-ref player-ref nil)))
+
+(defn start-playing [player-ref state-ref]
+ (when @player-ref
+ (.play ^js @player-ref #(if %
+ (update-state state-ref player-ref (.-message %))
+ (update-state state-ref player-ref nil)))))
+
+(defn stop-playing [player-ref state-ref]
+ (when @player-ref
+ (.stop ^js @player-ref #(if %
+ (update-state state-ref player-ref (.-message %))
+ (update-state state-ref player-ref nil)))))
+
+(defview message-content [{:keys [audio]}]
+ (letsubs [player (reagent/atom nil)
+ state (reagent/atom nil)]
+ {:component-did-mount (fn []
+ (reload-player player audio state))
+ :component-will-unmount (fn []
+ (destroy-player player))}
+ [react/view {:style {:margin-bottom 16}}
+ [button/button {:label (if (= (:general @state) :playing)
+ "stop"
+ "play")
+ :disabled? (or
+ (= (:general @state) :preparing)
+ (= (:general @state) :error))
+ :theme :green
+ :on-press (if (= (:general @state) :playing)
+ #(stop-playing player state)
+ #(start-playing player state))}]
+ [react/text {:style {:typography :main-medium}} (:error-msg @state)]]))
diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs
index 129f6acd18bc..1dfe47ec5aed 100644
--- a/src/status_im/ui/screens/chat/message/message.cljs
+++ b/src/status_im/ui/screens/chat/message/message.cljs
@@ -5,6 +5,7 @@
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
+ [status-im.ui.screens.chat.message.audio :as message.audio]
[status-im.ui.screens.chat.message.command :as message.command]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.chat.sheets :as sheets]
@@ -298,6 +299,13 @@
{:content (sheets/sticker-long-press message)
:height 64}])}))
+(defn message-content-audio
+ [message]
+ [react/touchable-highlight (message.audio/message-press-handlers message)
+ [message-bubble-wrapper message
+ [message.audio/message-content message]
+ [message-timestamp message true]]])
+
(defn chat-message [{:keys [public? content content-type] :as message}]
(if (= content-type constants/content-type-command)
[message.command/command-content message-content-wrapper message]
@@ -322,4 +330,8 @@
(not public?))
[react/touchable-highlight (image-message-press-handlers message)
[message-content-image message]]
- [unknown-content-type message])))))])))
+ (if (and (= content-type constants/content-type-audio)
+ ;; Disabling audio for public-chats
+ (not public?))
+ [message-content-audio message]
+ [unknown-content-type message]))))))])))
diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs
index cf01c2abc475..7eee8f0d1b94 100644
--- a/src/status_im/ui/screens/chat/views.cljs
+++ b/src/status_im/ui/screens/chat/views.cljs
@@ -9,6 +9,7 @@
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.screens.chat.input.input :as input]
+ [status-im.ui.screens.chat.audio-message.views :as audio-message]
[status-im.ui.screens.chat.message.message :as message]
[status-im.ui.screens.chat.stickers.views :as stickers]
[status-im.ui.screens.chat.styles.main :as style]
@@ -181,6 +182,8 @@
[extensions/extensions-view]
:images
[image/image-view]
+ :audio-message
+ [audio-message/audio-message-view]
[empty-bottom-sheet])))
(defview chat []
diff --git a/src/status_im/utils/fs.cljs b/src/status_im/utils/fs.cljs
index ca7a3fdceb31..df2a951452d3 100644
--- a/src/status_im/utils/fs.cljs
+++ b/src/status_im/utils/fs.cljs
@@ -4,6 +4,11 @@
(defn move-file [src dst]
(.moveFile react-native-fs src dst))
+(defn stat [path on-stat on-error]
+ (-> (.stat react-native-fs path)
+ (.then on-stat)
+ (.catch on-error)))
+
(defn read-file [path encoding on-read on-error]
(-> (.readFile react-native-fs path encoding)
(.then on-read)
diff --git a/status-go-version.json b/status-go-version.json
index 996566ac4530..e0c4044d7ed4 100644
--- a/status-go-version.json
+++ b/status-go-version.json
@@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' instead",
"owner": "status-im",
"repo": "status-go",
- "version": "v0.54.1",
- "commit-sha1": "20f45a7c1caa25a30853480ac47177b534536f26",
- "src-sha256": "1hsjsv00dlbjp4nqnifymldr8v20arzv07l9l27jarq9dk00wbia"
+ "version": "feature/audio-messages",
+ "commit-sha1": "f74f8f9d5264848e1a74322c8b86f5cdc8a69af2",
+ "src-sha256": "0k37ym6xj9xvyibcvyhhd6n9m9h2dcx5a1g12gbb3yf1b142dnbh"
}