stream-chat-react 9.2.0 → 9.4.1

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.
Files changed (28) hide show
  1. package/dist/browser.full-bundle.js +1180 -2912
  2. package/dist/browser.full-bundle.js.map +1 -1
  3. package/dist/browser.full-bundle.min.js +4 -4
  4. package/dist/browser.full-bundle.min.js.map +1 -1
  5. package/dist/components/Channel/channelState.d.ts.map +1 -1
  6. package/dist/components/Channel/channelState.js +2 -2
  7. package/dist/components/ChatAutoComplete/ChatAutoComplete.d.ts +12 -1
  8. package/dist/components/ChatAutoComplete/ChatAutoComplete.d.ts.map +1 -1
  9. package/dist/components/Message/MessageStatus.d.ts +2 -0
  10. package/dist/components/Message/MessageStatus.d.ts.map +1 -1
  11. package/dist/components/Message/MessageStatus.js +4 -4
  12. package/dist/components/Message/utils.d.ts +10 -1
  13. package/dist/components/Message/utils.d.ts.map +1 -1
  14. package/dist/components/Message/utils.js +13 -4
  15. package/dist/components/MessageInput/hooks/useSubmitHandler.d.ts.map +1 -1
  16. package/dist/components/MessageInput/hooks/useSubmitHandler.js +1 -1
  17. package/dist/index.cjs.js +751 -15
  18. package/dist/index.cjs.js.map +1 -1
  19. package/dist/stories/message-status-readby-tooltip.stories.d.ts +4 -0
  20. package/dist/stories/message-status-readby-tooltip.stories.d.ts.map +1 -0
  21. package/dist/stories/message-status-readby-tooltip.stories.js +58 -0
  22. package/dist/stories/navigate-long-message-lists.stories.d.ts.map +1 -1
  23. package/dist/stories/navigate-long-message-lists.stories.js +22 -2
  24. package/dist/utils.d.ts.map +1 -1
  25. package/dist/utils.js +17 -2
  26. package/dist/version.d.ts +1 -1
  27. package/dist/version.js +1 -1
  28. package/package.json +6 -3
package/dist/index.cjs.js CHANGED
@@ -32,7 +32,6 @@ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
32
32
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
33
33
  var emojiRegex = require('emoji-regex');
34
34
  var linkify = require('linkifyjs');
35
- var findAndReplace = require('mdast-util-find-and-replace');
36
35
  var RootReactMarkdown = require('react-markdown');
37
36
  var ReactMarkdown = require('react-markdown/with-html');
38
37
  var uniqBy = require('lodash.uniqby');
@@ -93,7 +92,6 @@ var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_definePropert
93
92
  var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
94
93
  var emojiRegex__default = /*#__PURE__*/_interopDefaultLegacy(emojiRegex);
95
94
  var linkify__namespace = /*#__PURE__*/_interopNamespace(linkify);
96
- var findAndReplace__default = /*#__PURE__*/_interopDefaultLegacy(findAndReplace);
97
95
  var RootReactMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(RootReactMarkdown);
98
96
  var ReactMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(ReactMarkdown);
99
97
  var uniqBy__default = /*#__PURE__*/_interopDefaultLegacy(uniqBy);
@@ -1333,6 +1331,718 @@ var withComponentContext = function (Component) {
1333
1331
  return WithComponentContextComponent;
1334
1332
  };
1335
1333
 
1334
+ function escapeStringRegexp(string) {
1335
+ if (typeof string !== 'string') {
1336
+ throw new TypeError('Expected a string');
1337
+ }
1338
+
1339
+ // Escape characters with special meaning either inside or outside character sets.
1340
+ // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.
1341
+ return string
1342
+ .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
1343
+ .replace(/-/g, '\\x2d');
1344
+ }
1345
+
1346
+ /**
1347
+ * @typedef {import('unist').Node} Node
1348
+ * @typedef {import('unist').Parent} Parent
1349
+ *
1350
+ * @typedef {string} Type
1351
+ * @typedef {Object<string, unknown>} Props
1352
+ *
1353
+ * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
1354
+ */
1355
+
1356
+ const convert$1 =
1357
+ /**
1358
+ * @type {(
1359
+ * (<T extends Node>(test: T['type']|Partial<T>|TestFunctionPredicate<T>) => AssertPredicate<T>) &
1360
+ * ((test?: Test) => AssertAnything)
1361
+ * )}
1362
+ */
1363
+ (
1364
+ /**
1365
+ * Generate an assertion from a check.
1366
+ * @param {Test} [test]
1367
+ * When nullish, checks if `node` is a `Node`.
1368
+ * When `string`, works like passing `function (node) {return node.type === test}`.
1369
+ * When `function` checks if function passed the node is true.
1370
+ * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
1371
+ * When `array`, checks any one of the subtests pass.
1372
+ * @returns {AssertAnything}
1373
+ */
1374
+ function (test) {
1375
+ if (test === undefined || test === null) {
1376
+ return ok$1
1377
+ }
1378
+
1379
+ if (typeof test === 'string') {
1380
+ return typeFactory$1(test)
1381
+ }
1382
+
1383
+ if (typeof test === 'object') {
1384
+ return Array.isArray(test) ? anyFactory$1(test) : propsFactory$1(test)
1385
+ }
1386
+
1387
+ if (typeof test === 'function') {
1388
+ return castFactory$1(test)
1389
+ }
1390
+
1391
+ throw new Error('Expected function, string, or object as test')
1392
+ }
1393
+ );
1394
+ /**
1395
+ * @param {Array.<Type|Props|TestFunctionAnything>} tests
1396
+ * @returns {AssertAnything}
1397
+ */
1398
+ function anyFactory$1(tests) {
1399
+ /** @type {Array.<AssertAnything>} */
1400
+ const checks = [];
1401
+ let index = -1;
1402
+
1403
+ while (++index < tests.length) {
1404
+ checks[index] = convert$1(tests[index]);
1405
+ }
1406
+
1407
+ return castFactory$1(any)
1408
+
1409
+ /**
1410
+ * @this {unknown}
1411
+ * @param {unknown[]} parameters
1412
+ * @returns {boolean}
1413
+ */
1414
+ function any(...parameters) {
1415
+ let index = -1;
1416
+
1417
+ while (++index < checks.length) {
1418
+ if (checks[index].call(this, ...parameters)) return true
1419
+ }
1420
+
1421
+ return false
1422
+ }
1423
+ }
1424
+
1425
+ /**
1426
+ * Utility to assert each property in `test` is represented in `node`, and each
1427
+ * values are strictly equal.
1428
+ *
1429
+ * @param {Props} check
1430
+ * @returns {AssertAnything}
1431
+ */
1432
+ function propsFactory$1(check) {
1433
+ return castFactory$1(all)
1434
+
1435
+ /**
1436
+ * @param {Node} node
1437
+ * @returns {boolean}
1438
+ */
1439
+ function all(node) {
1440
+ /** @type {string} */
1441
+ let key;
1442
+
1443
+ for (key in check) {
1444
+ // @ts-expect-error: hush, it sure works as an index.
1445
+ if (node[key] !== check[key]) return false
1446
+ }
1447
+
1448
+ return true
1449
+ }
1450
+ }
1451
+
1452
+ /**
1453
+ * Utility to convert a string into a function which checks a given node’s type
1454
+ * for said string.
1455
+ *
1456
+ * @param {Type} check
1457
+ * @returns {AssertAnything}
1458
+ */
1459
+ function typeFactory$1(check) {
1460
+ return castFactory$1(type)
1461
+
1462
+ /**
1463
+ * @param {Node} node
1464
+ */
1465
+ function type(node) {
1466
+ return node && node.type === check
1467
+ }
1468
+ }
1469
+
1470
+ /**
1471
+ * Utility to convert a string into a function which checks a given node’s type
1472
+ * for said string.
1473
+ * @param {TestFunctionAnything} check
1474
+ * @returns {AssertAnything}
1475
+ */
1476
+ function castFactory$1(check) {
1477
+ return assertion
1478
+
1479
+ /**
1480
+ * @this {unknown}
1481
+ * @param {Array.<unknown>} parameters
1482
+ * @returns {boolean}
1483
+ */
1484
+ function assertion(...parameters) {
1485
+ // @ts-expect-error: spreading is fine.
1486
+ return Boolean(check.call(this, ...parameters))
1487
+ }
1488
+ }
1489
+
1490
+ // Utility to return true.
1491
+ function ok$1() {
1492
+ return true
1493
+ }
1494
+
1495
+ /**
1496
+ * @param {string} d
1497
+ * @returns {string}
1498
+ */
1499
+ function color(d) {
1500
+ return '\u001B[33m' + d + '\u001B[39m'
1501
+ }
1502
+
1503
+ /**
1504
+ * @typedef {import('unist').Node} Node
1505
+ * @typedef {import('unist').Parent} Parent
1506
+ * @typedef {import('unist-util-is').Test} Test
1507
+ * @typedef {import('./complex-types').Action} Action
1508
+ * @typedef {import('./complex-types').Index} Index
1509
+ * @typedef {import('./complex-types').ActionTuple} ActionTuple
1510
+ * @typedef {import('./complex-types').VisitorResult} VisitorResult
1511
+ * @typedef {import('./complex-types').Visitor} Visitor
1512
+ */
1513
+
1514
+ /**
1515
+ * Continue traversing as normal
1516
+ */
1517
+ const CONTINUE = true;
1518
+ /**
1519
+ * Do not traverse this node’s children
1520
+ */
1521
+ const SKIP = 'skip';
1522
+ /**
1523
+ * Stop traversing immediately
1524
+ */
1525
+ const EXIT = false;
1526
+
1527
+ /**
1528
+ * Visit children of tree which pass a test
1529
+ *
1530
+ * @param tree Abstract syntax tree to walk
1531
+ * @param test Test node, optional
1532
+ * @param visitor Function to run for each node
1533
+ * @param reverse Visit the tree in reverse order, defaults to false
1534
+ */
1535
+ const visitParents =
1536
+ /**
1537
+ * @type {(
1538
+ * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
1539
+ * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types').BuildVisitor<Tree>, reverse?: boolean) => void)
1540
+ * )}
1541
+ */
1542
+ (
1543
+ /**
1544
+ * @param {Node} tree
1545
+ * @param {Test} test
1546
+ * @param {import('./complex-types').Visitor<Node>} visitor
1547
+ * @param {boolean} [reverse]
1548
+ */
1549
+ function (tree, test, visitor, reverse) {
1550
+ if (typeof test === 'function' && typeof visitor !== 'function') {
1551
+ reverse = visitor;
1552
+ // @ts-expect-error no visitor given, so `visitor` is test.
1553
+ visitor = test;
1554
+ test = null;
1555
+ }
1556
+
1557
+ const is = convert$1(test);
1558
+ const step = reverse ? -1 : 1;
1559
+
1560
+ factory(tree, null, [])();
1561
+
1562
+ /**
1563
+ * @param {Node} node
1564
+ * @param {number?} index
1565
+ * @param {Array.<Parent>} parents
1566
+ */
1567
+ function factory(node, index, parents) {
1568
+ /** @type {Object.<string, unknown>} */
1569
+ // @ts-expect-error: hush
1570
+ const value = typeof node === 'object' && node !== null ? node : {};
1571
+ /** @type {string|undefined} */
1572
+ let name;
1573
+
1574
+ if (typeof value.type === 'string') {
1575
+ name =
1576
+ typeof value.tagName === 'string'
1577
+ ? value.tagName
1578
+ : typeof value.name === 'string'
1579
+ ? value.name
1580
+ : undefined;
1581
+
1582
+ Object.defineProperty(visit, 'name', {
1583
+ value:
1584
+ 'node (' +
1585
+ color(value.type + (name ? '<' + name + '>' : '')) +
1586
+ ')'
1587
+ });
1588
+ }
1589
+
1590
+ return visit
1591
+
1592
+ function visit() {
1593
+ /** @type {ActionTuple} */
1594
+ let result = [];
1595
+ /** @type {ActionTuple} */
1596
+ let subresult;
1597
+ /** @type {number} */
1598
+ let offset;
1599
+ /** @type {Array.<Parent>} */
1600
+ let grandparents;
1601
+
1602
+ if (!test || is(node, index, parents[parents.length - 1] || null)) {
1603
+ result = toResult(visitor(node, parents));
1604
+
1605
+ if (result[0] === EXIT) {
1606
+ return result
1607
+ }
1608
+ }
1609
+
1610
+ // @ts-expect-error looks like a parent.
1611
+ if (node.children && result[0] !== SKIP) {
1612
+ // @ts-expect-error looks like a parent.
1613
+ offset = (reverse ? node.children.length : -1) + step;
1614
+ // @ts-expect-error looks like a parent.
1615
+ grandparents = parents.concat(node);
1616
+
1617
+ // @ts-expect-error looks like a parent.
1618
+ while (offset > -1 && offset < node.children.length) {
1619
+ // @ts-expect-error looks like a parent.
1620
+ subresult = factory(node.children[offset], offset, grandparents)();
1621
+
1622
+ if (subresult[0] === EXIT) {
1623
+ return subresult
1624
+ }
1625
+
1626
+ offset =
1627
+ typeof subresult[1] === 'number' ? subresult[1] : offset + step;
1628
+ }
1629
+ }
1630
+
1631
+ return result
1632
+ }
1633
+ }
1634
+ }
1635
+ );
1636
+
1637
+ /**
1638
+ * @param {VisitorResult} value
1639
+ * @returns {ActionTuple}
1640
+ */
1641
+ function toResult(value) {
1642
+ if (Array.isArray(value)) {
1643
+ return value
1644
+ }
1645
+
1646
+ if (typeof value === 'number') {
1647
+ return [CONTINUE, value]
1648
+ }
1649
+
1650
+ return [value]
1651
+ }
1652
+
1653
+ /**
1654
+ * @typedef {import('unist').Node} Node
1655
+ * @typedef {import('unist').Parent} Parent
1656
+ *
1657
+ * @typedef {string} Type
1658
+ * @typedef {Object<string, unknown>} Props
1659
+ *
1660
+ * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
1661
+ */
1662
+
1663
+ const convert =
1664
+ /**
1665
+ * @type {(
1666
+ * (<T extends Node>(test: T['type']|Partial<T>|TestFunctionPredicate<T>) => AssertPredicate<T>) &
1667
+ * ((test?: Test) => AssertAnything)
1668
+ * )}
1669
+ */
1670
+ (
1671
+ /**
1672
+ * Generate an assertion from a check.
1673
+ * @param {Test} [test]
1674
+ * When nullish, checks if `node` is a `Node`.
1675
+ * When `string`, works like passing `function (node) {return node.type === test}`.
1676
+ * When `function` checks if function passed the node is true.
1677
+ * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
1678
+ * When `array`, checks any one of the subtests pass.
1679
+ * @returns {AssertAnything}
1680
+ */
1681
+ function (test) {
1682
+ if (test === undefined || test === null) {
1683
+ return ok
1684
+ }
1685
+
1686
+ if (typeof test === 'string') {
1687
+ return typeFactory(test)
1688
+ }
1689
+
1690
+ if (typeof test === 'object') {
1691
+ return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
1692
+ }
1693
+
1694
+ if (typeof test === 'function') {
1695
+ return castFactory(test)
1696
+ }
1697
+
1698
+ throw new Error('Expected function, string, or object as test')
1699
+ }
1700
+ );
1701
+ /**
1702
+ * @param {Array.<Type|Props|TestFunctionAnything>} tests
1703
+ * @returns {AssertAnything}
1704
+ */
1705
+ function anyFactory(tests) {
1706
+ /** @type {Array.<AssertAnything>} */
1707
+ const checks = [];
1708
+ let index = -1;
1709
+
1710
+ while (++index < tests.length) {
1711
+ checks[index] = convert(tests[index]);
1712
+ }
1713
+
1714
+ return castFactory(any)
1715
+
1716
+ /**
1717
+ * @this {unknown}
1718
+ * @param {unknown[]} parameters
1719
+ * @returns {boolean}
1720
+ */
1721
+ function any(...parameters) {
1722
+ let index = -1;
1723
+
1724
+ while (++index < checks.length) {
1725
+ if (checks[index].call(this, ...parameters)) return true
1726
+ }
1727
+
1728
+ return false
1729
+ }
1730
+ }
1731
+
1732
+ /**
1733
+ * Utility to assert each property in `test` is represented in `node`, and each
1734
+ * values are strictly equal.
1735
+ *
1736
+ * @param {Props} check
1737
+ * @returns {AssertAnything}
1738
+ */
1739
+ function propsFactory(check) {
1740
+ return castFactory(all)
1741
+
1742
+ /**
1743
+ * @param {Node} node
1744
+ * @returns {boolean}
1745
+ */
1746
+ function all(node) {
1747
+ /** @type {string} */
1748
+ let key;
1749
+
1750
+ for (key in check) {
1751
+ // @ts-expect-error: hush, it sure works as an index.
1752
+ if (node[key] !== check[key]) return false
1753
+ }
1754
+
1755
+ return true
1756
+ }
1757
+ }
1758
+
1759
+ /**
1760
+ * Utility to convert a string into a function which checks a given node’s type
1761
+ * for said string.
1762
+ *
1763
+ * @param {Type} check
1764
+ * @returns {AssertAnything}
1765
+ */
1766
+ function typeFactory(check) {
1767
+ return castFactory(type)
1768
+
1769
+ /**
1770
+ * @param {Node} node
1771
+ */
1772
+ function type(node) {
1773
+ return node && node.type === check
1774
+ }
1775
+ }
1776
+
1777
+ /**
1778
+ * Utility to convert a string into a function which checks a given node’s type
1779
+ * for said string.
1780
+ * @param {TestFunctionAnything} check
1781
+ * @returns {AssertAnything}
1782
+ */
1783
+ function castFactory(check) {
1784
+ return assertion
1785
+
1786
+ /**
1787
+ * @this {unknown}
1788
+ * @param {Array.<unknown>} parameters
1789
+ * @returns {boolean}
1790
+ */
1791
+ function assertion(...parameters) {
1792
+ // @ts-expect-error: spreading is fine.
1793
+ return Boolean(check.call(this, ...parameters))
1794
+ }
1795
+ }
1796
+
1797
+ // Utility to return true.
1798
+ function ok() {
1799
+ return true
1800
+ }
1801
+
1802
+ /**
1803
+ * @typedef Options
1804
+ * Configuration (optional).
1805
+ * @property {Test} [ignore]
1806
+ * `unist-util-is` test used to assert parents
1807
+ *
1808
+ * @typedef {import('mdast').Root} Root
1809
+ * @typedef {import('mdast').Content} Content
1810
+ * @typedef {import('mdast').PhrasingContent} PhrasingContent
1811
+ * @typedef {import('mdast').Text} Text
1812
+ * @typedef {Content|Root} Node
1813
+ * @typedef {Exclude<Extract<Node, import('mdast').Parent>, Root>} Parent
1814
+ *
1815
+ * @typedef {import('unist-util-visit-parents').Test} Test
1816
+ * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
1817
+ *
1818
+ * @typedef RegExpMatchObject
1819
+ * @property {number} index
1820
+ * @property {string} input
1821
+ * @property {[Root, ...Array<Parent>, Text]} stack
1822
+ *
1823
+ * @typedef {string|RegExp} Find
1824
+ * @typedef {string|ReplaceFunction} Replace
1825
+ *
1826
+ * @typedef {[Find, Replace]} FindAndReplaceTuple
1827
+ * @typedef {Record<string, Replace>} FindAndReplaceSchema
1828
+ * @typedef {Array<FindAndReplaceTuple>} FindAndReplaceList
1829
+ *
1830
+ * @typedef {[RegExp, ReplaceFunction]} Pair
1831
+ * @typedef {Array<Pair>} Pairs
1832
+ */
1833
+
1834
+ const own = {}.hasOwnProperty;
1835
+
1836
+ /**
1837
+ * @param tree mdast tree
1838
+ * @param find Value to find and remove. When `string`, escaped and made into a global `RegExp`
1839
+ * @param [replace] Value to insert.
1840
+ * * When `string`, turned into a Text node.
1841
+ * * When `Function`, called with the results of calling `RegExp.exec` as
1842
+ * arguments, in which case it can return a single or a list of `Node`,
1843
+ * a `string` (which is wrapped in a `Text` node), or `false` to not replace
1844
+ * @param [options] Configuration.
1845
+ */
1846
+ const findAndReplace =
1847
+ /**
1848
+ * @type {(
1849
+ * ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) &
1850
+ * ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node)
1851
+ * )}
1852
+ **/
1853
+ (
1854
+ /**
1855
+ * @param {Node} tree
1856
+ * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find
1857
+ * @param {Replace|Options} [replace]
1858
+ * @param {Options} [options]
1859
+ */
1860
+ function (tree, find, replace, options) {
1861
+ /** @type {Options|undefined} */
1862
+ let settings;
1863
+ /** @type {FindAndReplaceSchema|FindAndReplaceList} */
1864
+ let schema;
1865
+
1866
+ if (typeof find === 'string' || find instanceof RegExp) {
1867
+ // @ts-expect-error don’t expect options twice.
1868
+ schema = [[find, replace]];
1869
+ settings = options;
1870
+ } else {
1871
+ schema = find;
1872
+ // @ts-expect-error don’t expect replace twice.
1873
+ settings = replace;
1874
+ }
1875
+
1876
+ if (!settings) {
1877
+ settings = {};
1878
+ }
1879
+
1880
+ const ignored = convert(settings.ignore || []);
1881
+ const pairs = toPairs(schema);
1882
+ let pairIndex = -1;
1883
+
1884
+ while (++pairIndex < pairs.length) {
1885
+ visitParents(tree, 'text', visitor);
1886
+ }
1887
+
1888
+ return tree
1889
+
1890
+ /** @type {import('unist-util-visit-parents/complex-types').BuildVisitor<Root, 'text'>} */
1891
+ function visitor(node, parents) {
1892
+ let index = -1;
1893
+ /** @type {Parent|undefined} */
1894
+ let grandparent;
1895
+
1896
+ while (++index < parents.length) {
1897
+ const parent = /** @type {Parent} */ (parents[index]);
1898
+
1899
+ if (
1900
+ ignored(
1901
+ parent,
1902
+ // @ts-expect-error mdast vs. unist parent.
1903
+ grandparent ? grandparent.children.indexOf(parent) : undefined,
1904
+ grandparent
1905
+ )
1906
+ ) {
1907
+ return
1908
+ }
1909
+
1910
+ grandparent = parent;
1911
+ }
1912
+
1913
+ if (grandparent) {
1914
+ // @ts-expect-error: stack is fine.
1915
+ return handler(node, parents)
1916
+ }
1917
+ }
1918
+
1919
+ /**
1920
+ * @param {Text} node
1921
+ * @param {[Root, ...Array<Parent>]} parents
1922
+ * @returns {VisitorResult}
1923
+ */
1924
+ function handler(node, parents) {
1925
+ const parent = parents[parents.length - 1];
1926
+ const find = pairs[pairIndex][0];
1927
+ const replace = pairs[pairIndex][1];
1928
+ let start = 0;
1929
+ // @ts-expect-error: TS is wrong, some of these children can be text.
1930
+ const index = parent.children.indexOf(node);
1931
+ let change = false;
1932
+ /** @type {Array<PhrasingContent>} */
1933
+ let nodes = [];
1934
+ /** @type {number|undefined} */
1935
+ let position;
1936
+
1937
+ find.lastIndex = 0;
1938
+
1939
+ let match = find.exec(node.value);
1940
+
1941
+ while (match) {
1942
+ position = match.index;
1943
+ /** @type {RegExpMatchObject} */
1944
+ const matchObject = {
1945
+ index: match.index,
1946
+ input: match.input,
1947
+ stack: [...parents, node]
1948
+ };
1949
+ let value = replace(...match, matchObject);
1950
+
1951
+ if (typeof value === 'string') {
1952
+ value = value.length > 0 ? {type: 'text', value} : undefined;
1953
+ }
1954
+
1955
+ if (value !== false) {
1956
+ if (start !== position) {
1957
+ nodes.push({
1958
+ type: 'text',
1959
+ value: node.value.slice(start, position)
1960
+ });
1961
+ }
1962
+
1963
+ if (Array.isArray(value)) {
1964
+ nodes.push(...value);
1965
+ } else if (value) {
1966
+ nodes.push(value);
1967
+ }
1968
+
1969
+ start = position + match[0].length;
1970
+ change = true;
1971
+ }
1972
+
1973
+ if (!find.global) {
1974
+ break
1975
+ }
1976
+
1977
+ match = find.exec(node.value);
1978
+ }
1979
+
1980
+ if (change) {
1981
+ if (start < node.value.length) {
1982
+ nodes.push({type: 'text', value: node.value.slice(start)});
1983
+ }
1984
+
1985
+ parent.children.splice(index, 1, ...nodes);
1986
+ } else {
1987
+ nodes = [node];
1988
+ }
1989
+
1990
+ return index + nodes.length
1991
+ }
1992
+ }
1993
+ );
1994
+
1995
+ /**
1996
+ * @param {FindAndReplaceSchema|FindAndReplaceList} schema
1997
+ * @returns {Pairs}
1998
+ */
1999
+ function toPairs(schema) {
2000
+ /** @type {Pairs} */
2001
+ const result = [];
2002
+
2003
+ if (typeof schema !== 'object') {
2004
+ throw new TypeError('Expected array or object as schema')
2005
+ }
2006
+
2007
+ if (Array.isArray(schema)) {
2008
+ let index = -1;
2009
+
2010
+ while (++index < schema.length) {
2011
+ result.push([
2012
+ toExpression(schema[index][0]),
2013
+ toFunction(schema[index][1])
2014
+ ]);
2015
+ }
2016
+ } else {
2017
+ /** @type {string} */
2018
+ let key;
2019
+
2020
+ for (key in schema) {
2021
+ if (own.call(schema, key)) {
2022
+ result.push([toExpression(key), toFunction(schema[key])]);
2023
+ }
2024
+ }
2025
+ }
2026
+
2027
+ return result
2028
+ }
2029
+
2030
+ /**
2031
+ * @param {Find} find
2032
+ * @returns {RegExp}
2033
+ */
2034
+ function toExpression(find) {
2035
+ return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find
2036
+ }
2037
+
2038
+ /**
2039
+ * @param {Replace} replace
2040
+ * @returns {ReplaceFunction}
2041
+ */
2042
+ function toFunction(replace) {
2043
+ return typeof replace === 'function' ? replace : () => replace
2044
+ }
2045
+
1336
2046
  var isOnlyEmojis = function (text) {
1337
2047
  if (!text)
1338
2048
  return false;
@@ -1413,7 +2123,7 @@ var emojiMarkdownPlugin = function () {
1413
2123
  };
1414
2124
  }
1415
2125
  var transform = function (markdownAST) {
1416
- findAndReplace__default['default'](markdownAST, emojiRegex__default['default'](), replace);
2126
+ findAndReplace(markdownAST, emojiRegex__default['default'](), replace);
1417
2127
  return markdownAST;
1418
2128
  };
1419
2129
  return transform;
@@ -1440,7 +2150,7 @@ var mentionsMarkdownPlugin = function (mentioned_users) { return function () {
1440
2150
  return markdownAST;
1441
2151
  }
1442
2152
  var mentionedUsersRegex = new RegExp(mentioned_usernames.map(function (username) { return "@" + username; }).join('|'), 'g');
1443
- findAndReplace__default['default'](markdownAST, mentionedUsersRegex, replace);
2153
+ findAndReplace(markdownAST, mentionedUsersRegex, replace);
1444
2154
  return markdownAST;
1445
2155
  };
1446
2156
  return transform;
@@ -1471,6 +2181,22 @@ var renderText = function (text, mentioned_users, options) {
1471
2181
  if (noParsingNeeded.length > 0 || linkIsInBlock)
1472
2182
  return;
1473
2183
  try {
2184
+ // special case for mentions:
2185
+ // it could happen that a user's name matches with an e-mail format pattern.
2186
+ // in that case, we check whether the found e-mail is actually a mention
2187
+ // by naively checking for an existence of @ sign in front of it.
2188
+ if (type === 'email' && mentioned_users) {
2189
+ var emailMatchesWithName = mentioned_users.some(function (u) { return u.name === value; });
2190
+ if (emailMatchesWithName) {
2191
+ newText = newText.replace(new RegExp(escapeRegExp(value), 'g'), function (match, position) {
2192
+ var isMention = newText.charAt(position - 1) === '@';
2193
+ // in case of mention, we leave the match in its original form,
2194
+ // and we let `mentionsMarkdownPlugin` to do its job
2195
+ return isMention ? match : "[" + match + "](" + encodeDecode(href) + ")";
2196
+ });
2197
+ return;
2198
+ }
2199
+ }
1474
2200
  var displayLink = type === 'email' ? value : formatUrlForDisplay(href);
1475
2201
  newText = newText.replace(new RegExp(escapeRegExp(value), 'g'), "[" + displayLink + "](" + encodeDecode(href) + ")");
1476
2202
  }
@@ -2547,7 +3273,7 @@ var channelReducer = function (state, action) {
2547
3273
  }
2548
3274
  case 'loadMoreFinished': {
2549
3275
  var hasMore = action.hasMore, messages = action.messages;
2550
- return __assign(__assign({}, state), { hasMore: hasMore, loadingMore: false, messages: messages });
3276
+ return __assign(__assign({}, state), { hasMore: hasMore, loadingMore: false, messages: messages, suppressAutoscroll: false });
2551
3277
  }
2552
3278
  case 'loadMoreNewerFinished': {
2553
3279
  var hasMoreNewer = action.hasMoreNewer, messages = action.messages;
@@ -2568,7 +3294,7 @@ var channelReducer = function (state, action) {
2568
3294
  case 'setLoadingMore': {
2569
3295
  var loadingMore = action.loadingMore;
2570
3296
  // suppress the autoscroll behavior
2571
- return __assign(__assign({}, state), { loadingMore: loadingMore, suppressAutoscroll: true });
3297
+ return __assign(__assign({}, state), { loadingMore: loadingMore, suppressAutoscroll: loadingMore });
2572
3298
  }
2573
3299
  case 'setLoadingMoreNewer': {
2574
3300
  var loadingMoreNewer = action.loadingMoreNewer;
@@ -3180,15 +3906,24 @@ var getNonImageAttachments = function (message) {
3180
3906
  }
3181
3907
  return message.attachments.filter(function (item) { return item.type !== 'image'; });
3182
3908
  };
3183
- var getReadByTooltipText = function (users, t, client) {
3909
+ /**
3910
+ * Default Tooltip Username mapper implementation.
3911
+ *
3912
+ * @param user the user.
3913
+ */
3914
+ var mapToUserNameOrId = function (user) { return user.name || user.id; };
3915
+ var getReadByTooltipText = function (users, t, client, tooltipUserNameMapper) {
3184
3916
  var outStr = '';
3185
3917
  if (!t) {
3186
- throw new Error('`getReadByTooltipText was called, but translation function is not available`');
3918
+ throw new Error('getReadByTooltipText was called, but translation function is not available');
3919
+ }
3920
+ if (!tooltipUserNameMapper) {
3921
+ throw new Error('getReadByTooltipText was called, but tooltipUserNameMapper function is not available');
3187
3922
  }
3188
3923
  // first filter out client user, so restLength won't count it
3189
3924
  var otherUsers = users
3190
3925
  .filter(function (item) { return item && (client === null || client === void 0 ? void 0 : client.user) && item.id !== client.user.id; })
3191
- .map(function (item) { return item.name || item.id; });
3926
+ .map(tooltipUserNameMapper);
3192
3927
  var slicedArr = otherUsers.slice(0, 5);
3193
3928
  var restLength = otherUsers.length - slicedArr.length;
3194
3929
  if (slicedArr.length === 1) {
@@ -3207,7 +3942,7 @@ var getReadByTooltipText = function (users, t, client) {
3207
3942
  // example: "bob, joe, sam and 4 more"
3208
3943
  if (restLength === 0) {
3209
3944
  // mutate slicedArr to remove last user to display it separately
3210
- var lastUser = slicedArr.splice(slicedArr.length - 2, 1);
3945
+ var lastUser = slicedArr.splice(slicedArr.length - 1, 1);
3211
3946
  outStr = t('{{ commaSeparatedUsers }}, and {{ lastUser }}', {
3212
3947
  commaSeparatedUsers: slicedArr.join(', '),
3213
3948
  lastUser: lastUser,
@@ -3460,10 +4195,10 @@ var Tooltip = function (props) {
3460
4195
 
3461
4196
  var UnMemoizedMessageStatus = function (props) {
3462
4197
  var _a;
3463
- var propAvatar = props.Avatar, _b = props.messageType, messageType = _b === void 0 ? 'simple' : _b;
4198
+ var propAvatar = props.Avatar, _b = props.messageType, messageType = _b === void 0 ? 'simple' : _b, _c = props.tooltipUserNameMapper, tooltipUserNameMapper = _c === void 0 ? mapToUserNameOrId : _c;
3464
4199
  var client = useChatContext('MessageStatus').client;
3465
4200
  var contextAvatar = useComponentContext('MessageStatus').Avatar;
3466
- var _c = useMessageContext('MessageStatus'), isMyMessage = _c.isMyMessage, lastReceivedId = _c.lastReceivedId, message = _c.message, readBy = _c.readBy, threadList = _c.threadList;
4201
+ var _d = useMessageContext('MessageStatus'), isMyMessage = _d.isMyMessage, lastReceivedId = _d.lastReceivedId, message = _d.message, readBy = _d.readBy, threadList = _d.threadList;
3467
4202
  var t = useTranslationContext('MessageStatus').t;
3468
4203
  var Avatar$1 = propAvatar || contextAvatar || Avatar;
3469
4204
  if (!isMyMessage() || message.type === 'error') {
@@ -3478,7 +4213,7 @@ var UnMemoizedMessageStatus = function (props) {
3478
4213
  if ((readBy === null || readBy === void 0 ? void 0 : readBy.length) && !threadList && !justReadByMe) {
3479
4214
  var lastReadUser = readBy.filter(function (item) { var _a; return item.id !== ((_a = client.user) === null || _a === void 0 ? void 0 : _a.id); })[0];
3480
4215
  return (React__default['default'].createElement("span", { className: "str-chat__message-" + messageType + "-status", "data-testid": 'message-status-read-by' },
3481
- React__default['default'].createElement(Tooltip, null, getReadByTooltipText(readBy, t, client)),
4216
+ React__default['default'].createElement(Tooltip, null, getReadByTooltipText(readBy, t, client, tooltipUserNameMapper)),
3482
4217
  React__default['default'].createElement(Avatar$1, { image: lastReadUser.image, name: lastReadUser.name || lastReadUser.id, size: 15, user: lastReadUser }),
3483
4218
  readBy.length > 2 && (React__default['default'].createElement("span", { className: "str-chat__message-" + messageType + "-status-number", "data-testid": 'message-status-read-by-many' }, readBy.length - 1))));
3484
4219
  }
@@ -5328,7 +6063,7 @@ var useSubmitHandler = function (props, state, dispatch, numberOfUploads) {
5328
6063
  _a.label = 1;
5329
6064
  case 1:
5330
6065
  _a.trys.push([1, 3, , 4]);
5331
- return [4 /*yield*/, editMessage(__assign(__assign({}, message), updatedMessage))];
6066
+ return [4 /*yield*/, editMessage(__assign(__assign(__assign({}, message), updatedMessage), customMessageData))];
5332
6067
  case 2:
5333
6068
  _a.sent();
5334
6069
  clearEditingState === null || clearEditingState === void 0 ? void 0 : clearEditingState();
@@ -7682,7 +8417,7 @@ var UnMemoizedChannelList = function (props) {
7682
8417
  */
7683
8418
  var ChannelList = React__default['default'].memo(UnMemoizedChannelList);
7684
8419
 
7685
- var version = '9.2.0';
8420
+ var version = '9.4.1';
7686
8421
 
7687
8422
  var useChat = function (_a) {
7688
8423
  var _b, _c;
@@ -9638,6 +10373,7 @@ exports.itTranslations = itTranslations;
9638
10373
  exports.jaTranslations = jaTranslations;
9639
10374
  exports.koTranslations = koTranslations;
9640
10375
  exports.makeDateMessageId = makeDateMessageId;
10376
+ exports.mapToUserNameOrId = mapToUserNameOrId;
9641
10377
  exports.markDownRenderers = markDownRenderers;
9642
10378
  exports.matchMarkdownLinks = matchMarkdownLinks;
9643
10379
  exports.mentionsMarkdownPlugin = mentionsMarkdownPlugin;