@robono/messaging-react-native 0.3.1 → 0.3.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.2 — 2026-11-03
4
+
5
+ - Wait for optional attachment screening before sending; keep cancellation responsive while checking.
6
+
7
+
3
8
  ## 0.3.1 — 2026-11-03
4
9
 
5
10
  Match Messenger’s bottom communication tools: keep the surrounding area on the chat background, place attachment/text/microphone controls inside one rounded field, and keep Send or the quick reaction outside it. Apply the same neutral field to recording and voice-only mode.
package/SBOM.spdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "spdxVersion": "SPDX-2.3",
3
3
  "dataLicense": "CC0-1.0",
4
4
  "SPDXID": "SPDXRef-DOCUMENT",
5
- "name": "@robono/messaging-react-native@0.3.1",
6
- "documentNamespace": "https://robono.com/sbom/messaging-react-native/0.3.1/e12a43a51836b6fb4b795f4fd364d7c879c993e7",
5
+ "name": "@robono/messaging-react-native@0.3.2",
6
+ "documentNamespace": "https://robono.com/sbom/messaging-react-native/0.3.2/7c7c4927b016f6233ad8e4563e02de9c8df27d60",
7
7
  "creationInfo": {
8
- "created": "2026-11-03T12:47:55.132Z",
8
+ "created": "2026-11-03T15:38:34.815Z",
9
9
  "creators": [
10
10
  "Organization: Robono (support@robono.com)"
11
11
  ]
@@ -14,11 +14,11 @@
14
14
  {
15
15
  "name": "@robono/messaging-react-native",
16
16
  "SPDXID": "SPDXRef-Package",
17
- "versionInfo": "0.3.1",
17
+ "versionInfo": "0.3.2",
18
18
  "downloadLocation": "NOASSERTION",
19
19
  "filesAnalyzed": true,
20
20
  "packageVerificationCode": {
21
- "packageVerificationCodeValue": "e12a43a51836b6fb4b795f4fd364d7c879c993e7"
21
+ "packageVerificationCodeValue": "7c7c4927b016f6233ad8e4563e02de9c8df27d60"
22
22
  },
23
23
  "licenseConcluded": "LicenseRef-RobonoSDK",
24
24
  "licenseDeclared": "LicenseRef-RobonoSDK",
@@ -36,11 +36,11 @@
36
36
  "checksums": [
37
37
  {
38
38
  "algorithm": "SHA256",
39
- "checksumValue": "c4503a7a48fbeff6b8fa3460c3f684c56dc0f167746cd337d14206a762dcf42d"
39
+ "checksumValue": "9af199e3a2c07244175c80fb3848beba06b8b365a400a011f93d22cc8ccd80be"
40
40
  },
41
41
  {
42
42
  "algorithm": "SHA1",
43
- "checksumValue": "6f022a2582b75a8c92917afb4e62d6ea76fbe8c4"
43
+ "checksumValue": "5edab04e1f038dcc9d814799e74174b272c3e5ce"
44
44
  }
45
45
  ],
46
46
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -435,11 +435,11 @@
435
435
  "checksums": [
436
436
  {
437
437
  "algorithm": "SHA256",
438
- "checksumValue": "9709b9948aed627153930c11ab38cef3b3fdab5de6a1b9c92c46ced8a9f21cb8"
438
+ "checksumValue": "a58315de5822ee5c90396f3542daddddf31c805fb3e8ac1d55a79f52f86c5eed"
439
439
  },
440
440
  {
441
441
  "algorithm": "SHA1",
442
- "checksumValue": "4c822b2ee4a4c2d87e2c7b02926d03b49215bfbd"
442
+ "checksumValue": "ab6a59c708c50768ab9edaeb69b2b1f6142579bf"
443
443
  }
444
444
  ],
445
445
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -663,11 +663,11 @@
663
663
  "checksums": [
664
664
  {
665
665
  "algorithm": "SHA256",
666
- "checksumValue": "83128dcd20a748a83660e7c1bec8429a6a58c0e78c7200b4a1d96c4a5892cc6d"
666
+ "checksumValue": "4cfb3f210d58092c6bd2926b67da7cbc438ce4f2ac7185d1977d883dd20354e3"
667
667
  },
668
668
  {
669
669
  "algorithm": "SHA1",
670
- "checksumValue": "e444ceb5bd0501058f72d1c75539d543b6f05691"
670
+ "checksumValue": "93d222559d86ea135e0ab217dafd2117056d7a1a"
671
671
  }
672
672
  ],
673
673
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -1138,11 +1138,11 @@
1138
1138
  "checksums": [
1139
1139
  {
1140
1140
  "algorithm": "SHA256",
1141
- "checksumValue": "837bee30b0a3347166cbcda13abfb30fb32837aa39bf597aa977528654ff62e1"
1141
+ "checksumValue": "b9d740fd5736a2923b783bb656d03670d6cd2ed3da634e66ae6fed1bfdfa07e0"
1142
1142
  },
1143
1143
  {
1144
1144
  "algorithm": "SHA1",
1145
- "checksumValue": "ef58bbd68c69fe7887f860a85efcc5fe495ab368"
1145
+ "checksumValue": "57094e1592981f31581226fb95c5236d536d62e5"
1146
1146
  }
1147
1147
  ],
1148
1148
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -1157,11 +1157,11 @@
1157
1157
  "checksums": [
1158
1158
  {
1159
1159
  "algorithm": "SHA256",
1160
- "checksumValue": "66ee579f6021964ccde2c8eb8bbe2bfbe0de4ad8b1397d8023d18fcd96b4fb0c"
1160
+ "checksumValue": "54617bb12f3f0bdbb38087f912fdcbc2bb1ae3447e4ad1894ed07b132029772a"
1161
1161
  },
1162
1162
  {
1163
1163
  "algorithm": "SHA1",
1164
- "checksumValue": "cc016a01e077570c7bd95450ba2ac4d5847ca6a6"
1164
+ "checksumValue": "c57a90074d6674aaaead7ecebcf74a7e89ceda0d"
1165
1165
  }
1166
1166
  ],
1167
1167
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -1209,8 +1209,46 @@
1209
1209
  "copyrightText": "Copyright (c) 2026 Add to Loop LLC."
1210
1210
  },
1211
1211
  {
1212
- "fileName": "./dist/media-ui.d.ts",
1212
+ "fileName": "./dist/media-screening.d.ts",
1213
1213
  "SPDXID": "SPDXRef-File-62",
1214
+ "checksums": [
1215
+ {
1216
+ "algorithm": "SHA256",
1217
+ "checksumValue": "383e692406babc6818fb0f724b2cbd923a974f3f13ead5d0c36f3dd31654ea7a"
1218
+ },
1219
+ {
1220
+ "algorithm": "SHA1",
1221
+ "checksumValue": "f77d2ea3deecc988b0a078c82eb260b06554564c"
1222
+ }
1223
+ ],
1224
+ "licenseConcluded": "LicenseRef-RobonoSDK",
1225
+ "licenseInfoInFiles": [
1226
+ "LicenseRef-RobonoSDK"
1227
+ ],
1228
+ "copyrightText": "Copyright (c) 2026 Add to Loop LLC."
1229
+ },
1230
+ {
1231
+ "fileName": "./dist/media-screening.js",
1232
+ "SPDXID": "SPDXRef-File-63",
1233
+ "checksums": [
1234
+ {
1235
+ "algorithm": "SHA256",
1236
+ "checksumValue": "7c9f665acca4831c8ba9adcbe20c7cbd97acdb0de74d33543fbdc1f5f9363e90"
1237
+ },
1238
+ {
1239
+ "algorithm": "SHA1",
1240
+ "checksumValue": "d6112024a7d00ac778c02964d4b00f613f1771e9"
1241
+ }
1242
+ ],
1243
+ "licenseConcluded": "LicenseRef-RobonoSDK",
1244
+ "licenseInfoInFiles": [
1245
+ "LicenseRef-RobonoSDK"
1246
+ ],
1247
+ "copyrightText": "Copyright (c) 2026 Add to Loop LLC."
1248
+ },
1249
+ {
1250
+ "fileName": "./dist/media-ui.d.ts",
1251
+ "SPDXID": "SPDXRef-File-64",
1214
1252
  "checksums": [
1215
1253
  {
1216
1254
  "algorithm": "SHA256",
@@ -1229,7 +1267,7 @@
1229
1267
  },
1230
1268
  {
1231
1269
  "fileName": "./dist/media-ui.js",
1232
- "SPDXID": "SPDXRef-File-63",
1270
+ "SPDXID": "SPDXRef-File-65",
1233
1271
  "checksums": [
1234
1272
  {
1235
1273
  "algorithm": "SHA256",
@@ -1248,7 +1286,7 @@
1248
1286
  },
1249
1287
  {
1250
1288
  "fileName": "./dist/message-links.d.ts",
1251
- "SPDXID": "SPDXRef-File-64",
1289
+ "SPDXID": "SPDXRef-File-66",
1252
1290
  "checksums": [
1253
1291
  {
1254
1292
  "algorithm": "SHA256",
@@ -1267,7 +1305,7 @@
1267
1305
  },
1268
1306
  {
1269
1307
  "fileName": "./dist/message-links.js",
1270
- "SPDXID": "SPDXRef-File-65",
1308
+ "SPDXID": "SPDXRef-File-67",
1271
1309
  "checksums": [
1272
1310
  {
1273
1311
  "algorithm": "SHA256",
@@ -1286,7 +1324,7 @@
1286
1324
  },
1287
1325
  {
1288
1326
  "fileName": "./dist/message-menu.d.ts",
1289
- "SPDXID": "SPDXRef-File-66",
1327
+ "SPDXID": "SPDXRef-File-68",
1290
1328
  "checksums": [
1291
1329
  {
1292
1330
  "algorithm": "SHA256",
@@ -1305,7 +1343,7 @@
1305
1343
  },
1306
1344
  {
1307
1345
  "fileName": "./dist/message-menu.js",
1308
- "SPDXID": "SPDXRef-File-67",
1346
+ "SPDXID": "SPDXRef-File-69",
1309
1347
  "checksums": [
1310
1348
  {
1311
1349
  "algorithm": "SHA256",
@@ -1324,7 +1362,7 @@
1324
1362
  },
1325
1363
  {
1326
1364
  "fileName": "./dist/message-order.d.ts",
1327
- "SPDXID": "SPDXRef-File-68",
1365
+ "SPDXID": "SPDXRef-File-70",
1328
1366
  "checksums": [
1329
1367
  {
1330
1368
  "algorithm": "SHA256",
@@ -1343,7 +1381,7 @@
1343
1381
  },
1344
1382
  {
1345
1383
  "fileName": "./dist/message-order.js",
1346
- "SPDXID": "SPDXRef-File-69",
1384
+ "SPDXID": "SPDXRef-File-71",
1347
1385
  "checksums": [
1348
1386
  {
1349
1387
  "algorithm": "SHA256",
@@ -1362,7 +1400,7 @@
1362
1400
  },
1363
1401
  {
1364
1402
  "fileName": "./dist/messenger-video-view.d.ts",
1365
- "SPDXID": "SPDXRef-File-70",
1403
+ "SPDXID": "SPDXRef-File-72",
1366
1404
  "checksums": [
1367
1405
  {
1368
1406
  "algorithm": "SHA256",
@@ -1381,7 +1419,7 @@
1381
1419
  },
1382
1420
  {
1383
1421
  "fileName": "./dist/messenger-video-view.js",
1384
- "SPDXID": "SPDXRef-File-71",
1422
+ "SPDXID": "SPDXRef-File-73",
1385
1423
  "checksums": [
1386
1424
  {
1387
1425
  "algorithm": "SHA256",
@@ -1400,7 +1438,7 @@
1400
1438
  },
1401
1439
  {
1402
1440
  "fileName": "./dist/native-outbox.d.ts",
1403
- "SPDXID": "SPDXRef-File-72",
1441
+ "SPDXID": "SPDXRef-File-74",
1404
1442
  "checksums": [
1405
1443
  {
1406
1444
  "algorithm": "SHA256",
@@ -1419,7 +1457,7 @@
1419
1457
  },
1420
1458
  {
1421
1459
  "fileName": "./dist/native-outbox.js",
1422
- "SPDXID": "SPDXRef-File-73",
1460
+ "SPDXID": "SPDXRef-File-75",
1423
1461
  "checksums": [
1424
1462
  {
1425
1463
  "algorithm": "SHA256",
@@ -1438,7 +1476,7 @@
1438
1476
  },
1439
1477
  {
1440
1478
  "fileName": "./dist/photo-gesture.d.ts",
1441
- "SPDXID": "SPDXRef-File-74",
1479
+ "SPDXID": "SPDXRef-File-76",
1442
1480
  "checksums": [
1443
1481
  {
1444
1482
  "algorithm": "SHA256",
@@ -1457,7 +1495,7 @@
1457
1495
  },
1458
1496
  {
1459
1497
  "fileName": "./dist/photo-gesture.js",
1460
- "SPDXID": "SPDXRef-File-75",
1498
+ "SPDXID": "SPDXRef-File-77",
1461
1499
  "checksums": [
1462
1500
  {
1463
1501
  "algorithm": "SHA256",
@@ -1476,7 +1514,7 @@
1476
1514
  },
1477
1515
  {
1478
1516
  "fileName": "./dist/polls.d.ts",
1479
- "SPDXID": "SPDXRef-File-76",
1517
+ "SPDXID": "SPDXRef-File-78",
1480
1518
  "checksums": [
1481
1519
  {
1482
1520
  "algorithm": "SHA256",
@@ -1495,7 +1533,7 @@
1495
1533
  },
1496
1534
  {
1497
1535
  "fileName": "./dist/polls.js",
1498
- "SPDXID": "SPDXRef-File-77",
1536
+ "SPDXID": "SPDXRef-File-79",
1499
1537
  "checksums": [
1500
1538
  {
1501
1539
  "algorithm": "SHA256",
@@ -1514,7 +1552,7 @@
1514
1552
  },
1515
1553
  {
1516
1554
  "fileName": "./dist/pollVoteQueue.d.ts",
1517
- "SPDXID": "SPDXRef-File-78",
1555
+ "SPDXID": "SPDXRef-File-80",
1518
1556
  "checksums": [
1519
1557
  {
1520
1558
  "algorithm": "SHA256",
@@ -1533,7 +1571,7 @@
1533
1571
  },
1534
1572
  {
1535
1573
  "fileName": "./dist/pollVoteQueue.js",
1536
- "SPDXID": "SPDXRef-File-79",
1574
+ "SPDXID": "SPDXRef-File-81",
1537
1575
  "checksums": [
1538
1576
  {
1539
1577
  "algorithm": "SHA256",
@@ -1552,7 +1590,7 @@
1552
1590
  },
1553
1591
  {
1554
1592
  "fileName": "./dist/popup.d.ts",
1555
- "SPDXID": "SPDXRef-File-80",
1593
+ "SPDXID": "SPDXRef-File-82",
1556
1594
  "checksums": [
1557
1595
  {
1558
1596
  "algorithm": "SHA256",
@@ -1571,7 +1609,7 @@
1571
1609
  },
1572
1610
  {
1573
1611
  "fileName": "./dist/popup.js",
1574
- "SPDXID": "SPDXRef-File-81",
1612
+ "SPDXID": "SPDXRef-File-83",
1575
1613
  "checksums": [
1576
1614
  {
1577
1615
  "algorithm": "SHA256",
@@ -1590,7 +1628,7 @@
1590
1628
  },
1591
1629
  {
1592
1630
  "fileName": "./dist/quick-send.d.ts",
1593
- "SPDXID": "SPDXRef-File-82",
1631
+ "SPDXID": "SPDXRef-File-84",
1594
1632
  "checksums": [
1595
1633
  {
1596
1634
  "algorithm": "SHA256",
@@ -1609,7 +1647,7 @@
1609
1647
  },
1610
1648
  {
1611
1649
  "fileName": "./dist/quick-send.js",
1612
- "SPDXID": "SPDXRef-File-83",
1650
+ "SPDXID": "SPDXRef-File-85",
1613
1651
  "checksums": [
1614
1652
  {
1615
1653
  "algorithm": "SHA256",
@@ -1628,7 +1666,7 @@
1628
1666
  },
1629
1667
  {
1630
1668
  "fileName": "./dist/recent-media.d.ts",
1631
- "SPDXID": "SPDXRef-File-84",
1669
+ "SPDXID": "SPDXRef-File-86",
1632
1670
  "checksums": [
1633
1671
  {
1634
1672
  "algorithm": "SHA256",
@@ -1647,7 +1685,7 @@
1647
1685
  },
1648
1686
  {
1649
1687
  "fileName": "./dist/recent-media.js",
1650
- "SPDXID": "SPDXRef-File-85",
1688
+ "SPDXID": "SPDXRef-File-87",
1651
1689
  "checksums": [
1652
1690
  {
1653
1691
  "algorithm": "SHA256",
@@ -1666,7 +1704,7 @@
1666
1704
  },
1667
1705
  {
1668
1706
  "fileName": "./dist/safety.d.ts",
1669
- "SPDXID": "SPDXRef-File-86",
1707
+ "SPDXID": "SPDXRef-File-88",
1670
1708
  "checksums": [
1671
1709
  {
1672
1710
  "algorithm": "SHA256",
@@ -1685,7 +1723,7 @@
1685
1723
  },
1686
1724
  {
1687
1725
  "fileName": "./dist/safety.js",
1688
- "SPDXID": "SPDXRef-File-87",
1726
+ "SPDXID": "SPDXRef-File-89",
1689
1727
  "checksums": [
1690
1728
  {
1691
1729
  "algorithm": "SHA256",
@@ -1704,7 +1742,7 @@
1704
1742
  },
1705
1743
  {
1706
1744
  "fileName": "./dist/saved.d.ts",
1707
- "SPDXID": "SPDXRef-File-88",
1745
+ "SPDXID": "SPDXRef-File-90",
1708
1746
  "checksums": [
1709
1747
  {
1710
1748
  "algorithm": "SHA256",
@@ -1723,7 +1761,7 @@
1723
1761
  },
1724
1762
  {
1725
1763
  "fileName": "./dist/saved.js",
1726
- "SPDXID": "SPDXRef-File-89",
1764
+ "SPDXID": "SPDXRef-File-91",
1727
1765
  "checksums": [
1728
1766
  {
1729
1767
  "algorithm": "SHA256",
@@ -1742,7 +1780,7 @@
1742
1780
  },
1743
1781
  {
1744
1782
  "fileName": "./dist/search.d.ts",
1745
- "SPDXID": "SPDXRef-File-90",
1783
+ "SPDXID": "SPDXRef-File-92",
1746
1784
  "checksums": [
1747
1785
  {
1748
1786
  "algorithm": "SHA256",
@@ -1761,7 +1799,7 @@
1761
1799
  },
1762
1800
  {
1763
1801
  "fileName": "./dist/search.js",
1764
- "SPDXID": "SPDXRef-File-91",
1802
+ "SPDXID": "SPDXRef-File-93",
1765
1803
  "checksums": [
1766
1804
  {
1767
1805
  "algorithm": "SHA256",
@@ -1780,7 +1818,7 @@
1780
1818
  },
1781
1819
  {
1782
1820
  "fileName": "./dist/social.d.ts",
1783
- "SPDXID": "SPDXRef-File-92",
1821
+ "SPDXID": "SPDXRef-File-94",
1784
1822
  "checksums": [
1785
1823
  {
1786
1824
  "algorithm": "SHA256",
@@ -1799,7 +1837,7 @@
1799
1837
  },
1800
1838
  {
1801
1839
  "fileName": "./dist/social.js",
1802
- "SPDXID": "SPDXRef-File-93",
1840
+ "SPDXID": "SPDXRef-File-95",
1803
1841
  "checksums": [
1804
1842
  {
1805
1843
  "algorithm": "SHA256",
@@ -1818,7 +1856,7 @@
1818
1856
  },
1819
1857
  {
1820
1858
  "fileName": "./dist/translation-settings.d.ts",
1821
- "SPDXID": "SPDXRef-File-94",
1859
+ "SPDXID": "SPDXRef-File-96",
1822
1860
  "checksums": [
1823
1861
  {
1824
1862
  "algorithm": "SHA256",
@@ -1837,7 +1875,7 @@
1837
1875
  },
1838
1876
  {
1839
1877
  "fileName": "./dist/translation-settings.js",
1840
- "SPDXID": "SPDXRef-File-95",
1878
+ "SPDXID": "SPDXRef-File-97",
1841
1879
  "checksums": [
1842
1880
  {
1843
1881
  "algorithm": "SHA256",
@@ -1856,7 +1894,7 @@
1856
1894
  },
1857
1895
  {
1858
1896
  "fileName": "./dist/use-quote-gesture.d.ts",
1859
- "SPDXID": "SPDXRef-File-96",
1897
+ "SPDXID": "SPDXRef-File-98",
1860
1898
  "checksums": [
1861
1899
  {
1862
1900
  "algorithm": "SHA256",
@@ -1875,7 +1913,7 @@
1875
1913
  },
1876
1914
  {
1877
1915
  "fileName": "./dist/use-quote-gesture.js",
1878
- "SPDXID": "SPDXRef-File-97",
1916
+ "SPDXID": "SPDXRef-File-99",
1879
1917
  "checksums": [
1880
1918
  {
1881
1919
  "algorithm": "SHA256",
@@ -1894,7 +1932,7 @@
1894
1932
  },
1895
1933
  {
1896
1934
  "fileName": "./dist/visual/icon-nodes.d.ts",
1897
- "SPDXID": "SPDXRef-File-98",
1935
+ "SPDXID": "SPDXRef-File-100",
1898
1936
  "checksums": [
1899
1937
  {
1900
1938
  "algorithm": "SHA256",
@@ -1913,7 +1951,7 @@
1913
1951
  },
1914
1952
  {
1915
1953
  "fileName": "./dist/visual/icon-nodes.js",
1916
- "SPDXID": "SPDXRef-File-99",
1954
+ "SPDXID": "SPDXRef-File-101",
1917
1955
  "checksums": [
1918
1956
  {
1919
1957
  "algorithm": "SHA256",
@@ -1932,7 +1970,7 @@
1932
1970
  },
1933
1971
  {
1934
1972
  "fileName": "./dist/visual/icon-paths.d.ts",
1935
- "SPDXID": "SPDXRef-File-100",
1973
+ "SPDXID": "SPDXRef-File-102",
1936
1974
  "checksums": [
1937
1975
  {
1938
1976
  "algorithm": "SHA256",
@@ -1951,7 +1989,7 @@
1951
1989
  },
1952
1990
  {
1953
1991
  "fileName": "./dist/visual/icon-paths.js",
1954
- "SPDXID": "SPDXRef-File-101",
1992
+ "SPDXID": "SPDXRef-File-103",
1955
1993
  "checksums": [
1956
1994
  {
1957
1995
  "algorithm": "SHA256",
@@ -1970,7 +2008,7 @@
1970
2008
  },
1971
2009
  {
1972
2010
  "fileName": "./dist/visual/RobonoIcon.d.ts",
1973
- "SPDXID": "SPDXRef-File-102",
2011
+ "SPDXID": "SPDXRef-File-104",
1974
2012
  "checksums": [
1975
2013
  {
1976
2014
  "algorithm": "SHA256",
@@ -1989,7 +2027,7 @@
1989
2027
  },
1990
2028
  {
1991
2029
  "fileName": "./dist/visual/RobonoIcon.js",
1992
- "SPDXID": "SPDXRef-File-103",
2030
+ "SPDXID": "SPDXRef-File-105",
1993
2031
  "checksums": [
1994
2032
  {
1995
2033
  "algorithm": "SHA256",
@@ -2008,7 +2046,7 @@
2008
2046
  },
2009
2047
  {
2010
2048
  "fileName": "./dist/visual/weather-artwork.d.ts",
2011
- "SPDXID": "SPDXRef-File-104",
2049
+ "SPDXID": "SPDXRef-File-106",
2012
2050
  "checksums": [
2013
2051
  {
2014
2052
  "algorithm": "SHA256",
@@ -2027,7 +2065,7 @@
2027
2065
  },
2028
2066
  {
2029
2067
  "fileName": "./dist/visual/weather-artwork.js",
2030
- "SPDXID": "SPDXRef-File-105",
2068
+ "SPDXID": "SPDXRef-File-107",
2031
2069
  "checksums": [
2032
2070
  {
2033
2071
  "algorithm": "SHA256",
@@ -2046,7 +2084,7 @@
2046
2084
  },
2047
2085
  {
2048
2086
  "fileName": "./dist/visual/weather-conditions.d.ts",
2049
- "SPDXID": "SPDXRef-File-106",
2087
+ "SPDXID": "SPDXRef-File-108",
2050
2088
  "checksums": [
2051
2089
  {
2052
2090
  "algorithm": "SHA256",
@@ -2065,7 +2103,7 @@
2065
2103
  },
2066
2104
  {
2067
2105
  "fileName": "./dist/visual/weather-conditions.js",
2068
- "SPDXID": "SPDXRef-File-107",
2106
+ "SPDXID": "SPDXRef-File-109",
2069
2107
  "checksums": [
2070
2108
  {
2071
2109
  "algorithm": "SHA256",
@@ -2084,7 +2122,7 @@
2084
2122
  },
2085
2123
  {
2086
2124
  "fileName": "./dist/visual/WeatherArtwork.d.ts",
2087
- "SPDXID": "SPDXRef-File-108",
2125
+ "SPDXID": "SPDXRef-File-110",
2088
2126
  "checksums": [
2089
2127
  {
2090
2128
  "algorithm": "SHA256",
@@ -2103,7 +2141,7 @@
2103
2141
  },
2104
2142
  {
2105
2143
  "fileName": "./dist/visual/WeatherArtwork.js",
2106
- "SPDXID": "SPDXRef-File-109",
2144
+ "SPDXID": "SPDXRef-File-111",
2107
2145
  "checksums": [
2108
2146
  {
2109
2147
  "algorithm": "SHA256",
@@ -2122,7 +2160,7 @@
2122
2160
  },
2123
2161
  {
2124
2162
  "fileName": "./dist/voice-composer.d.ts",
2125
- "SPDXID": "SPDXRef-File-110",
2163
+ "SPDXID": "SPDXRef-File-112",
2126
2164
  "checksums": [
2127
2165
  {
2128
2166
  "algorithm": "SHA256",
@@ -2141,7 +2179,7 @@
2141
2179
  },
2142
2180
  {
2143
2181
  "fileName": "./dist/voice-composer.js",
2144
- "SPDXID": "SPDXRef-File-111",
2182
+ "SPDXID": "SPDXRef-File-113",
2145
2183
  "checksums": [
2146
2184
  {
2147
2185
  "algorithm": "SHA256",
@@ -2160,7 +2198,7 @@
2160
2198
  },
2161
2199
  {
2162
2200
  "fileName": "./dist/voice-waveform.d.ts",
2163
- "SPDXID": "SPDXRef-File-112",
2201
+ "SPDXID": "SPDXRef-File-114",
2164
2202
  "checksums": [
2165
2203
  {
2166
2204
  "algorithm": "SHA256",
@@ -2179,7 +2217,7 @@
2179
2217
  },
2180
2218
  {
2181
2219
  "fileName": "./dist/voice-waveform.js",
2182
- "SPDXID": "SPDXRef-File-113",
2220
+ "SPDXID": "SPDXRef-File-115",
2183
2221
  "checksums": [
2184
2222
  {
2185
2223
  "algorithm": "SHA256",
@@ -2198,7 +2236,7 @@
2198
2236
  },
2199
2237
  {
2200
2238
  "fileName": "./licenses/robono-icons-lucide-license.txt",
2201
- "SPDXID": "SPDXRef-File-114",
2239
+ "SPDXID": "SPDXRef-File-116",
2202
2240
  "checksums": [
2203
2241
  {
2204
2242
  "algorithm": "SHA256",
@@ -2217,7 +2255,7 @@
2217
2255
  },
2218
2256
  {
2219
2257
  "fileName": "./licenses/robono-icons-weather-attribution.txt",
2220
- "SPDXID": "SPDXRef-File-115",
2258
+ "SPDXID": "SPDXRef-File-117",
2221
2259
  "checksums": [
2222
2260
  {
2223
2261
  "algorithm": "SHA256",
@@ -2236,7 +2274,7 @@
2236
2274
  },
2237
2275
  {
2238
2276
  "fileName": "./licenses/robono-icons-weather-license.txt",
2239
- "SPDXID": "SPDXRef-File-116",
2277
+ "SPDXID": "SPDXRef-File-118",
2240
2278
  "checksums": [
2241
2279
  {
2242
2280
  "algorithm": "SHA256",
@@ -2255,15 +2293,15 @@
2255
2293
  },
2256
2294
  {
2257
2295
  "fileName": "./package.json",
2258
- "SPDXID": "SPDXRef-File-117",
2296
+ "SPDXID": "SPDXRef-File-119",
2259
2297
  "checksums": [
2260
2298
  {
2261
2299
  "algorithm": "SHA256",
2262
- "checksumValue": "a1b6ec7d61021c4af7d5a7def803f80fbf648790123b98298375573cddeacf96"
2300
+ "checksumValue": "f866a465d4d88faaa63726301dfff1818e89ace4373ad72e401a19c6f2ff5f9b"
2263
2301
  },
2264
2302
  {
2265
2303
  "algorithm": "SHA1",
2266
- "checksumValue": "730c85cc174ed787867f6b0090fa6ad1db375c39"
2304
+ "checksumValue": "ef809d7ff2addfdcc39f2aded2391b45fdd2651b"
2267
2305
  }
2268
2306
  ],
2269
2307
  "licenseConcluded": "LicenseRef-RobonoSDK",
@@ -2274,7 +2312,7 @@
2274
2312
  },
2275
2313
  {
2276
2314
  "fileName": "./plugin/preserve-call-audio.cjs",
2277
- "SPDXID": "SPDXRef-File-118",
2315
+ "SPDXID": "SPDXRef-File-120",
2278
2316
  "checksums": [
2279
2317
  {
2280
2318
  "algorithm": "SHA256",
@@ -2892,6 +2930,16 @@
2892
2930
  "spdxElementId": "SPDXRef-Package",
2893
2931
  "relationshipType": "CONTAINS",
2894
2932
  "relatedSpdxElement": "SPDXRef-File-118"
2933
+ },
2934
+ {
2935
+ "spdxElementId": "SPDXRef-Package",
2936
+ "relationshipType": "CONTAINS",
2937
+ "relatedSpdxElement": "SPDXRef-File-119"
2938
+ },
2939
+ {
2940
+ "spdxElementId": "SPDXRef-Package",
2941
+ "relationshipType": "CONTAINS",
2942
+ "relatedSpdxElement": "SPDXRef-File-120"
2895
2943
  }
2896
2944
  ],
2897
2945
  "hasExtractedLicensingInfos": [
@@ -1,3 +1,4 @@
1
+ import { awaitMediaScreening } from './media-screening';
1
2
  import { AudioModule, RecordingPresets, createAudioPlayer, setAudioModeAsync } from 'expo-audio';
2
3
  import * as Picker from 'expo-image-picker';
3
4
  import * as Documents from 'expo-document-picker';
@@ -261,8 +262,8 @@ export function createExpoMessagingStorage(options) {
261
262
  try {
262
263
  const response = await (options.fetch ?? fetch)(endpoint, { method: 'POST', redirect: 'error', signal: bounded.signal, headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` }, body: JSON.stringify({ ...input, operation }) });
263
264
  const result = await response.json();
264
- if (!response.ok) {
265
- const error = Object.assign(Error(result?.error?.message ?? 'The file could not be transferred. Try again.'), { status: response.status });
265
+ if (!response.ok || result?.error) {
266
+ const error = Object.assign(Error(result?.error?.message ?? 'The file could not be transferred. Try again.'), { status: response.status, code: result?.error?.code });
266
267
  throw error;
267
268
  }
268
269
  return result;
@@ -313,7 +314,7 @@ export function createExpoMessagingStorage(options) {
313
314
  },
314
315
  async upload(file, context) {
315
316
  const { uri, ...metadata } = file;
316
- const plan = await request('prepare', { uploadId: context.uploadId, conversationId: context.conversationId, kind: context.kind, file: metadata }, context.signal);
317
+ const plan = await awaitMediaScreening(() => request('prepare', { uploadId: context.uploadId, conversationId: context.conversationId, kind: context.kind, file: metadata }, context.signal), context.signal, context.onProcessing);
317
318
  check(context.signal);
318
319
  if (plan.media)
319
320
  return plan.media;
@@ -328,7 +329,7 @@ export function createExpoMessagingStorage(options) {
328
329
  for (let attempt = 0;; attempt++) {
329
330
  check(context.signal);
330
331
  try {
331
- const complete = await request('complete', { uploadId: context.uploadId, conversationId: context.conversationId }, context.signal);
332
+ const complete = await awaitMediaScreening(() => request('complete', { uploadId: context.uploadId, conversationId: context.conversationId }, context.signal), context.signal, context.onProcessing);
332
333
  return complete.media;
333
334
  }
334
335
  catch (error) {
@@ -350,7 +350,7 @@ export function MessagingMediaOverlay({ controller, audio, appearance, inlineVoi
350
350
  return _jsx(Modal, { transparent: true, visible: state.phase !== 'idle' && state.phase !== 'choosing', onDismiss: onDismiss, animationType: "fade", onRequestClose: () => { if (expanded)
351
351
  setExpanded(false);
352
352
  else
353
- void controller.cancel(); }, children: _jsx(SafeAreaProvider, { style: { flex: 1, backgroundColor: state.kind === 'image' || state.kind === 'video' ? 'rgba(0,0,0,0.94)' : messagingPopupBackdrop }, children: _jsx(SafeAreaView, { edges: expanded ? [] : ['top', 'bottom', 'left', 'right'], style: { flex: 1 }, children: _jsx(View, { style: { flex: 1, margin: state.kind === 'image' || state.kind === 'video' ? 0 : 8, borderRadius: state.kind === 'image' || state.kind === 'video' ? 0 : 18, overflow: 'hidden', backgroundColor: state.kind === 'image' || state.kind === 'video' ? 'transparent' : '#000000' }, children: viewer ?? (_jsx(View, { style: { flex: 1, backgroundColor: c.background }, children: _jsxs(ScrollView, { contentContainerStyle: { padding: 8, paddingTop: 0, gap: 12, flexGrow: 1 }, children: [_jsx(MessagingPopupHeader, { title: state.kind === 'voice' ? 'Voice message' : state.kind === 'image' ? 'Photo' : state.kind === 'video' ? 'Video' : 'File', foreground: c.foreground, closeLabel: "Close attachment", onClose: () => void controller.cancel() }), state.phase === 'recording' ? _jsxs(View, { style: { alignItems: 'center', gap: 20, paddingVertical: 32 }, children: [_jsx(MaterialIcons, { name: "mic", size: 48, color: c.accent }), _jsx(Text, { style: { color: c.foreground, fontSize: 32, fontVariant: ['tabular-nums'] }, children: time(state.elapsedMs) }), _jsxs(Text, { style: { color: c.secondary }, children: [time(Math.max(0, state.maxDurationMs - state.elapsedMs)), " remaining"] }), _jsx(Control, { label: "Stop recording", icon: "stop", color: c.accent, onPress: () => void controller.finishRecording() })] }) : null, ['choosing', 'preparing', 'uploading', 'opening'].includes(state.phase) && _jsx(Text, { accessibilityRole: "progressbar", accessibilityValue: { min: 0, max: 100, now: Math.round(state.progress * 100) }, style: { color: c.foreground, fontSize: 18 }, children: state.phase === 'uploading' ? `Uploading… ${Math.round(state.progress * 100)}%` : state.phase === 'opening' ? (state.progress > 0 ? `Opening… ${Math.round(state.progress * 100)}%` : 'Opening…') : state.phase === 'choosing' ? 'Choose an attachment.' : 'Preparing recording…' }), state.file && _jsxs(_Fragment, { children: [_jsx(Text, { style: { color: c.foreground, fontSize: 16 }, children: state.file.fileName }), _jsx(Text, { style: { color: c.secondary }, children: size(state.file.byteSize) }), (review || state.phase === 'viewing') && _jsx(FileViewer, { file: state.file, kind: state.kind, audio: audio, design: appearance }, state.file.uri)] }), state.error && _jsx(Text, { accessibilityRole: "alert", style: { color: c.foreground }, children: state.error }), review && (state.phase === 'review' || state.retryUpload) && _jsx(Control, { label: state.phase === 'failed' ? 'Retry upload' : 'Add attachment', icon: state.phase === 'failed' ? 'refresh' : 'send', color: c.accent, onPress: () => void controller.send() })] }) })) }) }) }) });
353
+ void controller.cancel(); }, children: _jsx(SafeAreaProvider, { style: { flex: 1, backgroundColor: state.kind === 'image' || state.kind === 'video' ? 'rgba(0,0,0,0.94)' : messagingPopupBackdrop }, children: _jsx(SafeAreaView, { edges: expanded ? [] : ['top', 'bottom', 'left', 'right'], style: { flex: 1 }, children: _jsx(View, { style: { flex: 1, margin: state.kind === 'image' || state.kind === 'video' ? 0 : 8, borderRadius: state.kind === 'image' || state.kind === 'video' ? 0 : 18, overflow: 'hidden', backgroundColor: state.kind === 'image' || state.kind === 'video' ? 'transparent' : '#000000' }, children: viewer ?? (_jsx(View, { style: { flex: 1, backgroundColor: c.background }, children: _jsxs(ScrollView, { contentContainerStyle: { padding: 8, paddingTop: 0, gap: 12, flexGrow: 1 }, children: [_jsx(MessagingPopupHeader, { title: state.kind === 'voice' ? 'Voice message' : state.kind === 'image' ? 'Photo' : state.kind === 'video' ? 'Video' : 'File', foreground: c.foreground, closeLabel: "Close attachment", onClose: () => void controller.cancel() }), state.phase === 'recording' ? _jsxs(View, { style: { alignItems: 'center', gap: 20, paddingVertical: 32 }, children: [_jsx(MaterialIcons, { name: "mic", size: 48, color: c.accent }), _jsx(Text, { style: { color: c.foreground, fontSize: 32, fontVariant: ['tabular-nums'] }, children: time(state.elapsedMs) }), _jsxs(Text, { style: { color: c.secondary }, children: [time(Math.max(0, state.maxDurationMs - state.elapsedMs)), " remaining"] }), _jsx(Control, { label: "Stop recording", icon: "stop", color: c.accent, onPress: () => void controller.finishRecording() })] }) : null, ['choosing', 'preparing', 'uploading', 'opening'].includes(state.phase) && _jsx(Text, { accessibilityRole: "progressbar", accessibilityValue: { min: 0, max: 100, now: Math.round(state.progress * 100) }, style: { color: c.foreground, fontSize: 18 }, children: state.phase === 'uploading' ? (state.processing ? 'Checking attachment… You can cancel.' : `Uploading… ${Math.round(state.progress * 100)}%`) : state.phase === 'opening' ? (state.progress > 0 ? `Opening… ${Math.round(state.progress * 100)}%` : 'Opening…') : state.phase === 'choosing' ? 'Choose an attachment.' : 'Preparing recording…' }), state.file && _jsxs(_Fragment, { children: [_jsx(Text, { style: { color: c.foreground, fontSize: 16 }, children: state.file.fileName }), _jsx(Text, { style: { color: c.secondary }, children: size(state.file.byteSize) }), (review || state.phase === 'viewing') && _jsx(FileViewer, { file: state.file, kind: state.kind, audio: audio, design: appearance }, state.file.uri)] }), state.error && _jsx(Text, { accessibilityRole: "alert", style: { color: c.foreground }, children: state.error }), review && (state.phase === 'review' || state.retryUpload) && _jsx(Control, { label: state.phase === 'failed' ? 'Retry upload' : 'Add attachment', icon: state.phase === 'failed' ? 'refresh' : 'send', color: c.accent, onPress: () => void controller.send() })] }) })) }) }) }) });
354
354
  }
355
355
  /** Optional ready-made recording, preview, upload and download tools for both mobile platforms. */
356
356
  export function ExpoMessagingScreen({ storage, audioSession, renderConversation, preloadRecentMedia = true, ...props }) {
@@ -12,6 +12,7 @@ export interface LocalMessagingMedia extends Omit<MessageMedia, 'assetId'> {
12
12
  export interface MediaTransferOptions {
13
13
  signal: AbortSignal;
14
14
  onProgress: (fraction: number) => void;
15
+ onProcessing?: () => void;
15
16
  }
16
17
  export interface MessagingMediaStorage {
17
18
  /** Keep uploadId stable on retry. Verify bytes/type/duration on the backend before returning. */
@@ -51,6 +52,7 @@ export interface MessagingMediaState {
51
52
  progress: number;
52
53
  error: string | null;
53
54
  retryUpload: boolean;
55
+ processing?: boolean;
54
56
  waveform?: number[];
55
57
  }
56
58
  /** Single attachment lifecycle shared by iOS and Android. Cancellation invalidates every late result. */
@@ -269,9 +269,10 @@ export class MessagingMediaController {
269
269
  resolve?.(media);
270
270
  return;
271
271
  }
272
- this.update({ phase: 'uploading', progress: 0, error: null, retryUpload: false });
272
+ this.update({ phase: 'uploading', progress: 0, error: null, retryUpload: false, processing: false });
273
273
  retryUpload = true;
274
- const media = await this.options.storage.upload(file, { uploadId, conversationId: this.conversationId, kind: this.state.kind, signal: abort.signal, onProgress: f => { if (this.isCurrent(g))
274
+ const media = await this.options.storage.upload(file, { uploadId, conversationId: this.conversationId, kind: this.state.kind, signal: abort.signal, onProcessing: () => { if (this.isCurrent(g))
275
+ this.update({ processing: true }); }, onProgress: f => { if (this.isCurrent(g))
275
276
  this.update({ progress: Math.max(0, Math.min(1, f)) }); } });
276
277
  retryUpload = false;
277
278
  if (!this.isCurrent(g)) {
@@ -0,0 +1,5 @@
1
+ /** Wait between short authenticated requests; never occupy a backend request for a video job. */
2
+ export declare function awaitMediaScreening<T>(request: () => Promise<T>, signal: AbortSignal, onPending?: () => void, options?: {
3
+ timeoutMs?: number;
4
+ pollMs?: number;
5
+ }): Promise<T>;
@@ -0,0 +1,31 @@
1
+ /** Wait between short authenticated requests; never occupy a backend request for a video job. */
2
+ export async function awaitMediaScreening(request, signal, onPending, options = {}) {
3
+ const deadline = Date.now() + (options.timeoutMs ?? 600000);
4
+ while (true) {
5
+ signal.throwIfAborted();
6
+ try {
7
+ const value = await request();
8
+ const error = value?.error;
9
+ if (error?.code === 'screening_pending')
10
+ throw Object.assign(Error(error.message), { code: error.code });
11
+ if (error)
12
+ throw Object.assign(Error(error.message ?? 'Attachment request failed.'), { code: error.code });
13
+ return value;
14
+ }
15
+ catch (e) {
16
+ if (e.code !== 'screening_pending')
17
+ throw e;
18
+ signal.throwIfAborted();
19
+ onPending?.();
20
+ if (Date.now() >= deadline)
21
+ throw Object.assign(Error('This attachment is still being checked. Retry to check its status; it has not been sent.'), { code: 'screening_pending', retryable: true });
22
+ await new Promise((resolve, reject) => {
23
+ const cancel = () => { clearTimeout(timer); signal.removeEventListener('abort', cancel); reject(Error('Cancelled')); };
24
+ const timer = setTimeout(() => { signal.removeEventListener('abort', cancel); resolve(); }, options.pollMs ?? 3000);
25
+ signal.addEventListener('abort', cancel, { once: true });
26
+ if (signal.aborted)
27
+ cancel();
28
+ });
29
+ }
30
+ }
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robono/messaging-react-native",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Optional, composable direct and group messaging screens for Robono.",