@plusscommunities/pluss-circles-web 1.5.1 → 1.5.2-beta.0

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/dist/index.cjs.js CHANGED
@@ -347,6 +347,35 @@ var circleActions = {
347
347
  }
348
348
 
349
349
  return sendMessage;
350
+ }(),
351
+ deleteMessage: function () {
352
+ var _deleteMessage = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(messageId, groupId) {
353
+ return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) {
354
+ while (1) {
355
+ switch (_context3.prev = _context3.next) {
356
+ case 0:
357
+ return _context3.abrupt("return", Session$4.authedFunction({
358
+ method: 'POST',
359
+ url: Helper$3.getUrl(values.serviceKey, 'update/deletemessage'),
360
+ data: {
361
+ messageId: messageId,
362
+ groupId: groupId
363
+ }
364
+ }));
365
+
366
+ case 1:
367
+ case "end":
368
+ return _context3.stop();
369
+ }
370
+ }
371
+ }, _callee3);
372
+ }));
373
+
374
+ function deleteMessage(_x7, _x8) {
375
+ return _deleteMessage.apply(this, arguments);
376
+ }
377
+
378
+ return deleteMessage;
350
379
  }()
351
380
  };
352
381
 
@@ -802,9 +831,9 @@ var Circles$1 = reactRedux.connect(mapStateToProps$3, {
802
831
  circleRemoved: circleRemoved
803
832
  })(Circles);
804
833
 
805
- function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
834
+ function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
806
835
 
807
- function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
836
+ function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
808
837
 
809
838
  function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; }
810
839
 
@@ -843,7 +872,7 @@ var AddCircle = /*#__PURE__*/function (_Component) {
843
872
  users: ___default['default'].sortBy(res.data.results.Items, function (u) {
844
873
  return (u.displayName || '').toLowerCase();
845
874
  }).map(function (u) {
846
- return _objectSpread$3(_objectSpread$3({}, u), {}, {
875
+ return _objectSpread$4(_objectSpread$4({}, u), {}, {
847
876
  userId: u.userId || u.Id
848
877
  });
849
878
  })
@@ -1379,6 +1408,10 @@ var AddCircle$1 = reactRedux.connect(mapStateToProps$2, {
1379
1408
  addRecentlyCreated: Actions$1.addRecentlyCreated
1380
1409
  })(reactRouter.withRouter(AddCircle));
1381
1410
 
1411
+ function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1412
+
1413
+ function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1414
+
1382
1415
  function _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$5(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; }
1383
1416
 
1384
1417
  function _isNativeReflectConstruct$5() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -1649,6 +1682,96 @@ var Circle = /*#__PURE__*/function (_Component) {
1649
1682
  }
1650
1683
  });
1651
1684
 
1685
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onDeleteMessage", function (message) {
1686
+ _this.setState({
1687
+ showDeleteConfirm: true,
1688
+ messageToDelete: message
1689
+ });
1690
+ });
1691
+
1692
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onConfirmDelete", /*#__PURE__*/_asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee4() {
1693
+ var messageToDelete, updatedMessages, revertedMessages;
1694
+ return _regeneratorRuntime__default['default'].wrap(function _callee4$(_context4) {
1695
+ while (1) {
1696
+ switch (_context4.prev = _context4.next) {
1697
+ case 0:
1698
+ messageToDelete = _this.state.messageToDelete;
1699
+
1700
+ if (messageToDelete) {
1701
+ _context4.next = 3;
1702
+ break;
1703
+ }
1704
+
1705
+ return _context4.abrupt("return");
1706
+
1707
+ case 3:
1708
+ // Optimistically update UI - mark as deleted immediately
1709
+ updatedMessages = _this.state.messages.map(function (m) {
1710
+ if (m._id === messageToDelete._id) {
1711
+ return _objectSpread$3(_objectSpread$3({}, m), {}, {
1712
+ deleted: true,
1713
+ text: ' '
1714
+ });
1715
+ }
1716
+
1717
+ return m;
1718
+ });
1719
+
1720
+ _this.setState({
1721
+ messages: updatedMessages,
1722
+ showDeleteConfirm: false,
1723
+ deletingMessageId: messageToDelete._id,
1724
+ messageToDelete: null
1725
+ });
1726
+
1727
+ _context4.prev = 5;
1728
+ _context4.next = 8;
1729
+ return circleActions.deleteMessage(messageToDelete._id, _this.state.circleId);
1730
+
1731
+ case 8:
1732
+ // Message already marked as deleted, just clear the deleting state
1733
+ _this.setState({
1734
+ deletingMessageId: null
1735
+ });
1736
+
1737
+ _context4.next = 17;
1738
+ break;
1739
+
1740
+ case 11:
1741
+ _context4.prev = 11;
1742
+ _context4.t0 = _context4["catch"](5);
1743
+ console.error('Failed to delete message:', _context4.t0); // Revert the optimistic update on failure
1744
+
1745
+ revertedMessages = _this.state.messages.map(function (m) {
1746
+ if (m._id === messageToDelete._id) {
1747
+ return messageToDelete;
1748
+ }
1749
+
1750
+ return m;
1751
+ });
1752
+
1753
+ _this.setState({
1754
+ messages: revertedMessages,
1755
+ deletingMessageId: null
1756
+ });
1757
+
1758
+ alert('Failed to delete message. Please try again.');
1759
+
1760
+ case 17:
1761
+ case "end":
1762
+ return _context4.stop();
1763
+ }
1764
+ }
1765
+ }, _callee4, null, [[5, 11]]);
1766
+ })));
1767
+
1768
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onCancelDelete", function () {
1769
+ _this.setState({
1770
+ showDeleteConfirm: false,
1771
+ messageToDelete: null
1772
+ });
1773
+ });
1774
+
1652
1775
  _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "sendMessage", function () {
1653
1776
  var message = {
1654
1777
  _id: Helper.randomString(),
@@ -1718,7 +1841,14 @@ var Circle = /*#__PURE__*/function (_Component) {
1718
1841
  images: [],
1719
1842
  files: [],
1720
1843
  membersExpanded: true,
1721
- replyingTo: null
1844
+ replyingTo: null,
1845
+ showDeleteConfirm: false,
1846
+ messageToDelete: null,
1847
+ deletingMessageId: null,
1848
+ imageInput: null,
1849
+ fileInput: null,
1850
+ imageInputShowing: false,
1851
+ fileInputShowing: false
1722
1852
  };
1723
1853
  return _this;
1724
1854
  }
@@ -1862,8 +1992,8 @@ var Circle = /*#__PURE__*/function (_Component) {
1862
1992
  display: this.state.imageInputShowing ? 'block' : 'none'
1863
1993
  }
1864
1994
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.ImageInput, {
1865
- ref: function ref(_ref4) {
1866
- _this5.imageInput = _ref4;
1995
+ ref: function ref(_ref5) {
1996
+ _this5.imageInput = _ref5;
1867
1997
  },
1868
1998
  multiple: true,
1869
1999
  limit: 10,
@@ -1877,8 +2007,8 @@ var Circle = /*#__PURE__*/function (_Component) {
1877
2007
  display: this.state.fileInputShowing ? 'block' : 'none'
1878
2008
  }
1879
2009
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.FileInput, {
1880
- ref: function ref(_ref5) {
1881
- _this5.fileInput = _ref5;
2010
+ ref: function ref(_ref6) {
2011
+ _this5.fileInput = _ref6;
1882
2012
  },
1883
2013
  multiple: true,
1884
2014
  limit: 10,
@@ -1904,9 +2034,11 @@ var Circle = /*#__PURE__*/function (_Component) {
1904
2034
  }
1905
2035
 
1906
2036
  var isSelf = m.user._id === this.props.user.Id;
2037
+ var isDeleted = m.deleted === true;
2038
+ var isDeleting = this.state.deletingMessageId === m._id;
1907
2039
  return /*#__PURE__*/React__default['default'].createElement("div", {
1908
2040
  key: m._id,
1909
- className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '')
2041
+ className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '').concat(isDeleting ? ' message-deleting' : '')
1910
2042
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1911
2043
  type: "h5-noUpper",
1912
2044
  className: "message_time"
@@ -1921,7 +2053,7 @@ var Circle = /*#__PURE__*/function (_Component) {
1921
2053
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1922
2054
  type: "body",
1923
2055
  className: "message_name"
1924
- }, m.user.name, m.replyingTo ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && /*#__PURE__*/React__default['default'].createElement("div", {
2056
+ }, m.user.name, m.replyingTo && !isDeleted ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && !isDeleted && /*#__PURE__*/React__default['default'].createElement("div", {
1925
2057
  className: "message_replyBubble"
1926
2058
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1927
2059
  type: "body",
@@ -1931,7 +2063,7 @@ var Circle = /*#__PURE__*/function (_Component) {
1931
2063
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1932
2064
  type: "body",
1933
2065
  className: "message_text"
1934
- }, Helper.toParagraphed(m.text)), /*#__PURE__*/React__default['default'].createElement("div", null, (m.image || []).map(function (url, i) {
2066
+ }, isDeleted ? '[Message deleted]' : Helper.toParagraphed(m.text)), !isDeleted && /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement("div", null, (m.image || []).map(function (url, i) {
1935
2067
  return /*#__PURE__*/React__default['default'].createElement("a", {
1936
2068
  href: url,
1937
2069
  target: "_blank",
@@ -1947,14 +2079,23 @@ var Circle = /*#__PURE__*/function (_Component) {
1947
2079
  key: i,
1948
2080
  white: isSelf
1949
2081
  });
1950
- }))), /*#__PURE__*/React__default['default'].createElement("div", {
1951
- className: "message_reply"
2082
+ })))), !isDeleted && /*#__PURE__*/React__default['default'].createElement("div", {
2083
+ className: "message_reply",
2084
+ style: {
2085
+ display: 'flex',
2086
+ gap: '16px'
2087
+ }
1952
2088
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1953
2089
  type: "button",
1954
2090
  onClick: function onClick() {
1955
2091
  _this6.onReply(m);
1956
2092
  }
1957
- }, "Reply")))));
2093
+ }, "Reply"), isSelf && /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
2094
+ type: "button",
2095
+ onClick: function onClick() {
2096
+ _this6.onDeleteMessage(m);
2097
+ }
2098
+ }, "Delete")))));
1958
2099
  }
1959
2100
  }, {
1960
2101
  key: "renderHeaderRight",
@@ -2020,7 +2161,7 @@ var Circle = /*#__PURE__*/function (_Component) {
2020
2161
  type: "formTitleMedium"
2021
2162
  }, "Image", Helper.getPluralS(this.state.images.length), " (", this.state.images.length, ")"))), this.state.imagesExpanded && /*#__PURE__*/React__default['default'].createElement("div", {
2022
2163
  className: "paddingTop-8"
2023
- }, this.state.images.map(function (image, i) {
2164
+ }, this.state.images.map(function (image) {
2024
2165
  return /*#__PURE__*/React__default['default'].createElement("a", {
2025
2166
  href: image.Url,
2026
2167
  target: "_blank"
@@ -2079,6 +2220,29 @@ var Circle = /*#__PURE__*/function (_Component) {
2079
2220
  colour: Colours$1.COLOUR_DUSK
2080
2221
  })));
2081
2222
  }
2223
+ }, {
2224
+ key: "renderDeleteConfirmPopup",
2225
+ value: function renderDeleteConfirmPopup() {
2226
+ if (!this.state.showDeleteConfirm) return null;
2227
+ return /*#__PURE__*/React__default['default'].createElement(Components$2.Popup, {
2228
+ title: "Delete Message",
2229
+ buttons: [{
2230
+ text: 'Delete',
2231
+ onClick: this.onConfirmDelete,
2232
+ type: 'primary',
2233
+ isActive: true
2234
+ }, {
2235
+ text: 'Cancel',
2236
+ onClick: this.onCancelDelete,
2237
+ type: 'tertiary',
2238
+ isActive: true
2239
+ }],
2240
+ onClose: this.onCancelDelete,
2241
+ hasPadding: true
2242
+ }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
2243
+ type: "body"
2244
+ }, "Are you sure you want to delete this message? This action cannot be undone."));
2245
+ }
2082
2246
  }, {
2083
2247
  key: "render",
2084
2248
  value: function render() {
@@ -2090,7 +2254,7 @@ var Circle = /*#__PURE__*/function (_Component) {
2090
2254
  display: 'flex',
2091
2255
  flexDirection: 'column'
2092
2256
  }
2093
- }, /*#__PURE__*/React__default['default'].createElement(Components$2.Header, {
2257
+ }, this.renderDeleteConfirmPopup(), /*#__PURE__*/React__default['default'].createElement(Components$2.Header, {
2094
2258
  rightContent: this.renderHeaderRight()
2095
2259
  }, /*#__PURE__*/React__default['default'].createElement(FontAwesome__default['default'], {
2096
2260
  className: "header_back",
@@ -2138,8 +2302,8 @@ var Circle = /*#__PURE__*/function (_Component) {
2138
2302
  }, /*#__PURE__*/React__default['default'].createElement("div", {
2139
2303
  className: "chat_newMessage"
2140
2304
  }, this.renderChatInput()), this.renderReplyTo(), /*#__PURE__*/React__default['default'].createElement("div", {
2141
- ref: function ref(_ref6) {
2142
- return _this8.chat = _ref6;
2305
+ ref: function ref(_ref7) {
2306
+ return _this8.chat = _ref7;
2143
2307
  },
2144
2308
  className: "chat_messages"
2145
2309
  }, ___default['default'].isEmpty(this.state.messages) && !___default['default'].isEmpty(this.state.messageDate) && this.renderEmptyDate(), this.state.messages.map(function (m) {
package/dist/index.esm.js CHANGED
@@ -304,6 +304,35 @@ var circleActions = {
304
304
  }
305
305
 
306
306
  return sendMessage;
307
+ }(),
308
+ deleteMessage: function () {
309
+ var _deleteMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(messageId, groupId) {
310
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
311
+ while (1) {
312
+ switch (_context3.prev = _context3.next) {
313
+ case 0:
314
+ return _context3.abrupt("return", Session$4.authedFunction({
315
+ method: 'POST',
316
+ url: Helper$3.getUrl(values.serviceKey, 'update/deletemessage'),
317
+ data: {
318
+ messageId: messageId,
319
+ groupId: groupId
320
+ }
321
+ }));
322
+
323
+ case 1:
324
+ case "end":
325
+ return _context3.stop();
326
+ }
327
+ }
328
+ }, _callee3);
329
+ }));
330
+
331
+ function deleteMessage(_x7, _x8) {
332
+ return _deleteMessage.apply(this, arguments);
333
+ }
334
+
335
+ return deleteMessage;
307
336
  }()
308
337
  };
309
338
 
@@ -759,9 +788,9 @@ var Circles$1 = connect(mapStateToProps$3, {
759
788
  circleRemoved: circleRemoved
760
789
  })(Circles);
761
790
 
762
- function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
791
+ function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
763
792
 
764
- function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
793
+ function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
765
794
 
766
795
  function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
767
796
 
@@ -800,7 +829,7 @@ var AddCircle = /*#__PURE__*/function (_Component) {
800
829
  users: _.sortBy(res.data.results.Items, function (u) {
801
830
  return (u.displayName || '').toLowerCase();
802
831
  }).map(function (u) {
803
- return _objectSpread$3(_objectSpread$3({}, u), {}, {
832
+ return _objectSpread$4(_objectSpread$4({}, u), {}, {
804
833
  userId: u.userId || u.Id
805
834
  });
806
835
  })
@@ -1336,6 +1365,10 @@ var AddCircle$1 = connect(mapStateToProps$2, {
1336
1365
  addRecentlyCreated: Actions$1.addRecentlyCreated
1337
1366
  })(withRouter(AddCircle));
1338
1367
 
1368
+ function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1369
+
1370
+ function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1371
+
1339
1372
  function _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$5(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
1340
1373
 
1341
1374
  function _isNativeReflectConstruct$5() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -1606,6 +1639,96 @@ var Circle = /*#__PURE__*/function (_Component) {
1606
1639
  }
1607
1640
  });
1608
1641
 
1642
+ _defineProperty(_assertThisInitialized(_this), "onDeleteMessage", function (message) {
1643
+ _this.setState({
1644
+ showDeleteConfirm: true,
1645
+ messageToDelete: message
1646
+ });
1647
+ });
1648
+
1649
+ _defineProperty(_assertThisInitialized(_this), "onConfirmDelete", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
1650
+ var messageToDelete, updatedMessages, revertedMessages;
1651
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
1652
+ while (1) {
1653
+ switch (_context4.prev = _context4.next) {
1654
+ case 0:
1655
+ messageToDelete = _this.state.messageToDelete;
1656
+
1657
+ if (messageToDelete) {
1658
+ _context4.next = 3;
1659
+ break;
1660
+ }
1661
+
1662
+ return _context4.abrupt("return");
1663
+
1664
+ case 3:
1665
+ // Optimistically update UI - mark as deleted immediately
1666
+ updatedMessages = _this.state.messages.map(function (m) {
1667
+ if (m._id === messageToDelete._id) {
1668
+ return _objectSpread$3(_objectSpread$3({}, m), {}, {
1669
+ deleted: true,
1670
+ text: ' '
1671
+ });
1672
+ }
1673
+
1674
+ return m;
1675
+ });
1676
+
1677
+ _this.setState({
1678
+ messages: updatedMessages,
1679
+ showDeleteConfirm: false,
1680
+ deletingMessageId: messageToDelete._id,
1681
+ messageToDelete: null
1682
+ });
1683
+
1684
+ _context4.prev = 5;
1685
+ _context4.next = 8;
1686
+ return circleActions.deleteMessage(messageToDelete._id, _this.state.circleId);
1687
+
1688
+ case 8:
1689
+ // Message already marked as deleted, just clear the deleting state
1690
+ _this.setState({
1691
+ deletingMessageId: null
1692
+ });
1693
+
1694
+ _context4.next = 17;
1695
+ break;
1696
+
1697
+ case 11:
1698
+ _context4.prev = 11;
1699
+ _context4.t0 = _context4["catch"](5);
1700
+ console.error('Failed to delete message:', _context4.t0); // Revert the optimistic update on failure
1701
+
1702
+ revertedMessages = _this.state.messages.map(function (m) {
1703
+ if (m._id === messageToDelete._id) {
1704
+ return messageToDelete;
1705
+ }
1706
+
1707
+ return m;
1708
+ });
1709
+
1710
+ _this.setState({
1711
+ messages: revertedMessages,
1712
+ deletingMessageId: null
1713
+ });
1714
+
1715
+ alert('Failed to delete message. Please try again.');
1716
+
1717
+ case 17:
1718
+ case "end":
1719
+ return _context4.stop();
1720
+ }
1721
+ }
1722
+ }, _callee4, null, [[5, 11]]);
1723
+ })));
1724
+
1725
+ _defineProperty(_assertThisInitialized(_this), "onCancelDelete", function () {
1726
+ _this.setState({
1727
+ showDeleteConfirm: false,
1728
+ messageToDelete: null
1729
+ });
1730
+ });
1731
+
1609
1732
  _defineProperty(_assertThisInitialized(_this), "sendMessage", function () {
1610
1733
  var message = {
1611
1734
  _id: Helper.randomString(),
@@ -1675,7 +1798,14 @@ var Circle = /*#__PURE__*/function (_Component) {
1675
1798
  images: [],
1676
1799
  files: [],
1677
1800
  membersExpanded: true,
1678
- replyingTo: null
1801
+ replyingTo: null,
1802
+ showDeleteConfirm: false,
1803
+ messageToDelete: null,
1804
+ deletingMessageId: null,
1805
+ imageInput: null,
1806
+ fileInput: null,
1807
+ imageInputShowing: false,
1808
+ fileInputShowing: false
1679
1809
  };
1680
1810
  return _this;
1681
1811
  }
@@ -1819,8 +1949,8 @@ var Circle = /*#__PURE__*/function (_Component) {
1819
1949
  display: this.state.imageInputShowing ? 'block' : 'none'
1820
1950
  }
1821
1951
  }, /*#__PURE__*/React.createElement(Components$2.ImageInput, {
1822
- ref: function ref(_ref4) {
1823
- _this5.imageInput = _ref4;
1952
+ ref: function ref(_ref5) {
1953
+ _this5.imageInput = _ref5;
1824
1954
  },
1825
1955
  multiple: true,
1826
1956
  limit: 10,
@@ -1834,8 +1964,8 @@ var Circle = /*#__PURE__*/function (_Component) {
1834
1964
  display: this.state.fileInputShowing ? 'block' : 'none'
1835
1965
  }
1836
1966
  }, /*#__PURE__*/React.createElement(Components$2.FileInput, {
1837
- ref: function ref(_ref5) {
1838
- _this5.fileInput = _ref5;
1967
+ ref: function ref(_ref6) {
1968
+ _this5.fileInput = _ref6;
1839
1969
  },
1840
1970
  multiple: true,
1841
1971
  limit: 10,
@@ -1861,9 +1991,11 @@ var Circle = /*#__PURE__*/function (_Component) {
1861
1991
  }
1862
1992
 
1863
1993
  var isSelf = m.user._id === this.props.user.Id;
1994
+ var isDeleted = m.deleted === true;
1995
+ var isDeleting = this.state.deletingMessageId === m._id;
1864
1996
  return /*#__PURE__*/React.createElement("div", {
1865
1997
  key: m._id,
1866
- className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '')
1998
+ className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '').concat(isDeleting ? ' message-deleting' : '')
1867
1999
  }, /*#__PURE__*/React.createElement(Components$2.Text, {
1868
2000
  type: "h5-noUpper",
1869
2001
  className: "message_time"
@@ -1878,7 +2010,7 @@ var Circle = /*#__PURE__*/function (_Component) {
1878
2010
  }, /*#__PURE__*/React.createElement(Components$2.Text, {
1879
2011
  type: "body",
1880
2012
  className: "message_name"
1881
- }, m.user.name, m.replyingTo ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && /*#__PURE__*/React.createElement("div", {
2013
+ }, m.user.name, m.replyingTo && !isDeleted ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && !isDeleted && /*#__PURE__*/React.createElement("div", {
1882
2014
  className: "message_replyBubble"
1883
2015
  }, /*#__PURE__*/React.createElement(Components$2.Text, {
1884
2016
  type: "body",
@@ -1888,7 +2020,7 @@ var Circle = /*#__PURE__*/function (_Component) {
1888
2020
  }, /*#__PURE__*/React.createElement(Components$2.Text, {
1889
2021
  type: "body",
1890
2022
  className: "message_text"
1891
- }, Helper.toParagraphed(m.text)), /*#__PURE__*/React.createElement("div", null, (m.image || []).map(function (url, i) {
2023
+ }, isDeleted ? '[Message deleted]' : Helper.toParagraphed(m.text)), !isDeleted && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, (m.image || []).map(function (url, i) {
1892
2024
  return /*#__PURE__*/React.createElement("a", {
1893
2025
  href: url,
1894
2026
  target: "_blank",
@@ -1904,14 +2036,23 @@ var Circle = /*#__PURE__*/function (_Component) {
1904
2036
  key: i,
1905
2037
  white: isSelf
1906
2038
  });
1907
- }))), /*#__PURE__*/React.createElement("div", {
1908
- className: "message_reply"
2039
+ })))), !isDeleted && /*#__PURE__*/React.createElement("div", {
2040
+ className: "message_reply",
2041
+ style: {
2042
+ display: 'flex',
2043
+ gap: '16px'
2044
+ }
1909
2045
  }, /*#__PURE__*/React.createElement(Components$2.Text, {
1910
2046
  type: "button",
1911
2047
  onClick: function onClick() {
1912
2048
  _this6.onReply(m);
1913
2049
  }
1914
- }, "Reply")))));
2050
+ }, "Reply"), isSelf && /*#__PURE__*/React.createElement(Components$2.Text, {
2051
+ type: "button",
2052
+ onClick: function onClick() {
2053
+ _this6.onDeleteMessage(m);
2054
+ }
2055
+ }, "Delete")))));
1915
2056
  }
1916
2057
  }, {
1917
2058
  key: "renderHeaderRight",
@@ -1977,7 +2118,7 @@ var Circle = /*#__PURE__*/function (_Component) {
1977
2118
  type: "formTitleMedium"
1978
2119
  }, "Image", Helper.getPluralS(this.state.images.length), " (", this.state.images.length, ")"))), this.state.imagesExpanded && /*#__PURE__*/React.createElement("div", {
1979
2120
  className: "paddingTop-8"
1980
- }, this.state.images.map(function (image, i) {
2121
+ }, this.state.images.map(function (image) {
1981
2122
  return /*#__PURE__*/React.createElement("a", {
1982
2123
  href: image.Url,
1983
2124
  target: "_blank"
@@ -2036,6 +2177,29 @@ var Circle = /*#__PURE__*/function (_Component) {
2036
2177
  colour: Colours$1.COLOUR_DUSK
2037
2178
  })));
2038
2179
  }
2180
+ }, {
2181
+ key: "renderDeleteConfirmPopup",
2182
+ value: function renderDeleteConfirmPopup() {
2183
+ if (!this.state.showDeleteConfirm) return null;
2184
+ return /*#__PURE__*/React.createElement(Components$2.Popup, {
2185
+ title: "Delete Message",
2186
+ buttons: [{
2187
+ text: 'Delete',
2188
+ onClick: this.onConfirmDelete,
2189
+ type: 'primary',
2190
+ isActive: true
2191
+ }, {
2192
+ text: 'Cancel',
2193
+ onClick: this.onCancelDelete,
2194
+ type: 'tertiary',
2195
+ isActive: true
2196
+ }],
2197
+ onClose: this.onCancelDelete,
2198
+ hasPadding: true
2199
+ }, /*#__PURE__*/React.createElement(Components$2.Text, {
2200
+ type: "body"
2201
+ }, "Are you sure you want to delete this message? This action cannot be undone."));
2202
+ }
2039
2203
  }, {
2040
2204
  key: "render",
2041
2205
  value: function render() {
@@ -2047,7 +2211,7 @@ var Circle = /*#__PURE__*/function (_Component) {
2047
2211
  display: 'flex',
2048
2212
  flexDirection: 'column'
2049
2213
  }
2050
- }, /*#__PURE__*/React.createElement(Components$2.Header, {
2214
+ }, this.renderDeleteConfirmPopup(), /*#__PURE__*/React.createElement(Components$2.Header, {
2051
2215
  rightContent: this.renderHeaderRight()
2052
2216
  }, /*#__PURE__*/React.createElement(FontAwesome, {
2053
2217
  className: "header_back",
@@ -2095,8 +2259,8 @@ var Circle = /*#__PURE__*/function (_Component) {
2095
2259
  }, /*#__PURE__*/React.createElement("div", {
2096
2260
  className: "chat_newMessage"
2097
2261
  }, this.renderChatInput()), this.renderReplyTo(), /*#__PURE__*/React.createElement("div", {
2098
- ref: function ref(_ref6) {
2099
- return _this8.chat = _ref6;
2262
+ ref: function ref(_ref7) {
2263
+ return _this8.chat = _ref7;
2100
2264
  },
2101
2265
  className: "chat_messages"
2102
2266
  }, _.isEmpty(this.state.messages) && !_.isEmpty(this.state.messageDate) && this.renderEmptyDate(), this.state.messages.map(function (m) {
package/dist/index.umd.js CHANGED
@@ -327,6 +327,35 @@
327
327
  }
328
328
 
329
329
  return sendMessage;
330
+ }(),
331
+ deleteMessage: function () {
332
+ var _deleteMessage = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(messageId, groupId) {
333
+ return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) {
334
+ while (1) {
335
+ switch (_context3.prev = _context3.next) {
336
+ case 0:
337
+ return _context3.abrupt("return", Session$4.authedFunction({
338
+ method: 'POST',
339
+ url: Helper$3.getUrl(values.serviceKey, 'update/deletemessage'),
340
+ data: {
341
+ messageId: messageId,
342
+ groupId: groupId
343
+ }
344
+ }));
345
+
346
+ case 1:
347
+ case "end":
348
+ return _context3.stop();
349
+ }
350
+ }
351
+ }, _callee3);
352
+ }));
353
+
354
+ function deleteMessage(_x7, _x8) {
355
+ return _deleteMessage.apply(this, arguments);
356
+ }
357
+
358
+ return deleteMessage;
330
359
  }()
331
360
  };
332
361
 
@@ -782,9 +811,9 @@
782
811
  circleRemoved: circleRemoved
783
812
  })(Circles);
784
813
 
785
- function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
814
+ function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
786
815
 
787
- function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
816
+ function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
788
817
 
789
818
  function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; }
790
819
 
@@ -823,7 +852,7 @@
823
852
  users: ___default['default'].sortBy(res.data.results.Items, function (u) {
824
853
  return (u.displayName || '').toLowerCase();
825
854
  }).map(function (u) {
826
- return _objectSpread$3(_objectSpread$3({}, u), {}, {
855
+ return _objectSpread$4(_objectSpread$4({}, u), {}, {
827
856
  userId: u.userId || u.Id
828
857
  });
829
858
  })
@@ -1359,6 +1388,10 @@
1359
1388
  addRecentlyCreated: Actions$1.addRecentlyCreated
1360
1389
  })(reactRouter.withRouter(AddCircle));
1361
1390
 
1391
+ function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1392
+
1393
+ function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1394
+
1362
1395
  function _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$5(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; }
1363
1396
 
1364
1397
  function _isNativeReflectConstruct$5() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -1629,6 +1662,96 @@
1629
1662
  }
1630
1663
  });
1631
1664
 
1665
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onDeleteMessage", function (message) {
1666
+ _this.setState({
1667
+ showDeleteConfirm: true,
1668
+ messageToDelete: message
1669
+ });
1670
+ });
1671
+
1672
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onConfirmDelete", /*#__PURE__*/_asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee4() {
1673
+ var messageToDelete, updatedMessages, revertedMessages;
1674
+ return _regeneratorRuntime__default['default'].wrap(function _callee4$(_context4) {
1675
+ while (1) {
1676
+ switch (_context4.prev = _context4.next) {
1677
+ case 0:
1678
+ messageToDelete = _this.state.messageToDelete;
1679
+
1680
+ if (messageToDelete) {
1681
+ _context4.next = 3;
1682
+ break;
1683
+ }
1684
+
1685
+ return _context4.abrupt("return");
1686
+
1687
+ case 3:
1688
+ // Optimistically update UI - mark as deleted immediately
1689
+ updatedMessages = _this.state.messages.map(function (m) {
1690
+ if (m._id === messageToDelete._id) {
1691
+ return _objectSpread$3(_objectSpread$3({}, m), {}, {
1692
+ deleted: true,
1693
+ text: ' '
1694
+ });
1695
+ }
1696
+
1697
+ return m;
1698
+ });
1699
+
1700
+ _this.setState({
1701
+ messages: updatedMessages,
1702
+ showDeleteConfirm: false,
1703
+ deletingMessageId: messageToDelete._id,
1704
+ messageToDelete: null
1705
+ });
1706
+
1707
+ _context4.prev = 5;
1708
+ _context4.next = 8;
1709
+ return circleActions.deleteMessage(messageToDelete._id, _this.state.circleId);
1710
+
1711
+ case 8:
1712
+ // Message already marked as deleted, just clear the deleting state
1713
+ _this.setState({
1714
+ deletingMessageId: null
1715
+ });
1716
+
1717
+ _context4.next = 17;
1718
+ break;
1719
+
1720
+ case 11:
1721
+ _context4.prev = 11;
1722
+ _context4.t0 = _context4["catch"](5);
1723
+ console.error('Failed to delete message:', _context4.t0); // Revert the optimistic update on failure
1724
+
1725
+ revertedMessages = _this.state.messages.map(function (m) {
1726
+ if (m._id === messageToDelete._id) {
1727
+ return messageToDelete;
1728
+ }
1729
+
1730
+ return m;
1731
+ });
1732
+
1733
+ _this.setState({
1734
+ messages: revertedMessages,
1735
+ deletingMessageId: null
1736
+ });
1737
+
1738
+ alert('Failed to delete message. Please try again.');
1739
+
1740
+ case 17:
1741
+ case "end":
1742
+ return _context4.stop();
1743
+ }
1744
+ }
1745
+ }, _callee4, null, [[5, 11]]);
1746
+ })));
1747
+
1748
+ _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "onCancelDelete", function () {
1749
+ _this.setState({
1750
+ showDeleteConfirm: false,
1751
+ messageToDelete: null
1752
+ });
1753
+ });
1754
+
1632
1755
  _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "sendMessage", function () {
1633
1756
  var message = {
1634
1757
  _id: Helper.randomString(),
@@ -1698,7 +1821,14 @@
1698
1821
  images: [],
1699
1822
  files: [],
1700
1823
  membersExpanded: true,
1701
- replyingTo: null
1824
+ replyingTo: null,
1825
+ showDeleteConfirm: false,
1826
+ messageToDelete: null,
1827
+ deletingMessageId: null,
1828
+ imageInput: null,
1829
+ fileInput: null,
1830
+ imageInputShowing: false,
1831
+ fileInputShowing: false
1702
1832
  };
1703
1833
  return _this;
1704
1834
  }
@@ -1842,8 +1972,8 @@
1842
1972
  display: this.state.imageInputShowing ? 'block' : 'none'
1843
1973
  }
1844
1974
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.ImageInput, {
1845
- ref: function ref(_ref4) {
1846
- _this5.imageInput = _ref4;
1975
+ ref: function ref(_ref5) {
1976
+ _this5.imageInput = _ref5;
1847
1977
  },
1848
1978
  multiple: true,
1849
1979
  limit: 10,
@@ -1857,8 +1987,8 @@
1857
1987
  display: this.state.fileInputShowing ? 'block' : 'none'
1858
1988
  }
1859
1989
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.FileInput, {
1860
- ref: function ref(_ref5) {
1861
- _this5.fileInput = _ref5;
1990
+ ref: function ref(_ref6) {
1991
+ _this5.fileInput = _ref6;
1862
1992
  },
1863
1993
  multiple: true,
1864
1994
  limit: 10,
@@ -1884,9 +2014,11 @@
1884
2014
  }
1885
2015
 
1886
2016
  var isSelf = m.user._id === this.props.user.Id;
2017
+ var isDeleted = m.deleted === true;
2018
+ var isDeleting = this.state.deletingMessageId === m._id;
1887
2019
  return /*#__PURE__*/React__default['default'].createElement("div", {
1888
2020
  key: m._id,
1889
- className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '')
2021
+ className: "message".concat(isSelf ? ' message-self' : '').concat(m.uploading ? ' message-uploading' : '').concat(isDeleting ? ' message-deleting' : '')
1890
2022
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1891
2023
  type: "h5-noUpper",
1892
2024
  className: "message_time"
@@ -1901,7 +2033,7 @@
1901
2033
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1902
2034
  type: "body",
1903
2035
  className: "message_name"
1904
- }, m.user.name, m.replyingTo ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && /*#__PURE__*/React__default['default'].createElement("div", {
2036
+ }, m.user.name, m.replyingTo && !isDeleted ? " replied to ".concat(m.replyingTo.user.name) : ''), m.replyingTo && !isDeleted && /*#__PURE__*/React__default['default'].createElement("div", {
1905
2037
  className: "message_replyBubble"
1906
2038
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1907
2039
  type: "body",
@@ -1911,7 +2043,7 @@
1911
2043
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1912
2044
  type: "body",
1913
2045
  className: "message_text"
1914
- }, Helper.toParagraphed(m.text)), /*#__PURE__*/React__default['default'].createElement("div", null, (m.image || []).map(function (url, i) {
2046
+ }, isDeleted ? '[Message deleted]' : Helper.toParagraphed(m.text)), !isDeleted && /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement("div", null, (m.image || []).map(function (url, i) {
1915
2047
  return /*#__PURE__*/React__default['default'].createElement("a", {
1916
2048
  href: url,
1917
2049
  target: "_blank",
@@ -1927,14 +2059,23 @@
1927
2059
  key: i,
1928
2060
  white: isSelf
1929
2061
  });
1930
- }))), /*#__PURE__*/React__default['default'].createElement("div", {
1931
- className: "message_reply"
2062
+ })))), !isDeleted && /*#__PURE__*/React__default['default'].createElement("div", {
2063
+ className: "message_reply",
2064
+ style: {
2065
+ display: 'flex',
2066
+ gap: '16px'
2067
+ }
1932
2068
  }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
1933
2069
  type: "button",
1934
2070
  onClick: function onClick() {
1935
2071
  _this6.onReply(m);
1936
2072
  }
1937
- }, "Reply")))));
2073
+ }, "Reply"), isSelf && /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
2074
+ type: "button",
2075
+ onClick: function onClick() {
2076
+ _this6.onDeleteMessage(m);
2077
+ }
2078
+ }, "Delete")))));
1938
2079
  }
1939
2080
  }, {
1940
2081
  key: "renderHeaderRight",
@@ -2000,7 +2141,7 @@
2000
2141
  type: "formTitleMedium"
2001
2142
  }, "Image", Helper.getPluralS(this.state.images.length), " (", this.state.images.length, ")"))), this.state.imagesExpanded && /*#__PURE__*/React__default['default'].createElement("div", {
2002
2143
  className: "paddingTop-8"
2003
- }, this.state.images.map(function (image, i) {
2144
+ }, this.state.images.map(function (image) {
2004
2145
  return /*#__PURE__*/React__default['default'].createElement("a", {
2005
2146
  href: image.Url,
2006
2147
  target: "_blank"
@@ -2059,6 +2200,29 @@
2059
2200
  colour: Colours$1.COLOUR_DUSK
2060
2201
  })));
2061
2202
  }
2203
+ }, {
2204
+ key: "renderDeleteConfirmPopup",
2205
+ value: function renderDeleteConfirmPopup() {
2206
+ if (!this.state.showDeleteConfirm) return null;
2207
+ return /*#__PURE__*/React__default['default'].createElement(Components$2.Popup, {
2208
+ title: "Delete Message",
2209
+ buttons: [{
2210
+ text: 'Delete',
2211
+ onClick: this.onConfirmDelete,
2212
+ type: 'primary',
2213
+ isActive: true
2214
+ }, {
2215
+ text: 'Cancel',
2216
+ onClick: this.onCancelDelete,
2217
+ type: 'tertiary',
2218
+ isActive: true
2219
+ }],
2220
+ onClose: this.onCancelDelete,
2221
+ hasPadding: true
2222
+ }, /*#__PURE__*/React__default['default'].createElement(Components$2.Text, {
2223
+ type: "body"
2224
+ }, "Are you sure you want to delete this message? This action cannot be undone."));
2225
+ }
2062
2226
  }, {
2063
2227
  key: "render",
2064
2228
  value: function render() {
@@ -2070,7 +2234,7 @@
2070
2234
  display: 'flex',
2071
2235
  flexDirection: 'column'
2072
2236
  }
2073
- }, /*#__PURE__*/React__default['default'].createElement(Components$2.Header, {
2237
+ }, this.renderDeleteConfirmPopup(), /*#__PURE__*/React__default['default'].createElement(Components$2.Header, {
2074
2238
  rightContent: this.renderHeaderRight()
2075
2239
  }, /*#__PURE__*/React__default['default'].createElement(FontAwesome__default['default'], {
2076
2240
  className: "header_back",
@@ -2118,8 +2282,8 @@
2118
2282
  }, /*#__PURE__*/React__default['default'].createElement("div", {
2119
2283
  className: "chat_newMessage"
2120
2284
  }, this.renderChatInput()), this.renderReplyTo(), /*#__PURE__*/React__default['default'].createElement("div", {
2121
- ref: function ref(_ref6) {
2122
- return _this8.chat = _ref6;
2285
+ ref: function ref(_ref7) {
2286
+ return _this8.chat = _ref7;
2123
2287
  },
2124
2288
  className: "chat_messages"
2125
2289
  }, ___default['default'].isEmpty(this.state.messages) && !___default['default'].isEmpty(this.state.messageDate) && this.renderEmptyDate(), this.state.messages.map(function (m) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-circles-web",
3
- "version": "1.5.1",
3
+ "version": "1.5.2-beta.0",
4
4
  "description": "Extension package to enable circles on Pluss Communities Platform",
5
5
  "main": "dist/index.cjs.js",
6
6
  "scripts": {
@@ -103,4 +103,14 @@ export const circleActions = {
103
103
  },
104
104
  });
105
105
  },
106
+ deleteMessage: async (messageId, groupId) => {
107
+ return Session.authedFunction({
108
+ method: 'POST',
109
+ url: Helper.getUrl(values.serviceKey, 'update/deletemessage'),
110
+ data: {
111
+ messageId,
112
+ groupId,
113
+ },
114
+ });
115
+ },
106
116
  };
@@ -26,6 +26,13 @@ class Circle extends Component {
26
26
  files: [],
27
27
  membersExpanded: true,
28
28
  replyingTo: null,
29
+ showDeleteConfirm: false,
30
+ messageToDelete: null,
31
+ deletingMessageId: null,
32
+ imageInput: null,
33
+ fileInput: null,
34
+ imageInputShowing: false,
35
+ fileInputShowing: false,
29
36
  };
30
37
  }
31
38
 
@@ -256,6 +263,60 @@ class Circle extends Component {
256
263
  }
257
264
  };
258
265
 
266
+ onDeleteMessage = (message) => {
267
+ this.setState({
268
+ showDeleteConfirm: true,
269
+ messageToDelete: message,
270
+ });
271
+ };
272
+
273
+ onConfirmDelete = async () => {
274
+ const { messageToDelete } = this.state;
275
+ if (!messageToDelete) return;
276
+
277
+ // Optimistically update UI - mark as deleted immediately
278
+ const updatedMessages = this.state.messages.map((m) => {
279
+ if (m._id === messageToDelete._id) {
280
+ return { ...m, deleted: true, text: ' ' };
281
+ }
282
+ return m;
283
+ });
284
+
285
+ this.setState({
286
+ messages: updatedMessages,
287
+ showDeleteConfirm: false,
288
+ deletingMessageId: messageToDelete._id,
289
+ messageToDelete: null,
290
+ });
291
+
292
+ try {
293
+ await circleActions.deleteMessage(messageToDelete._id, this.state.circleId);
294
+ // Message already marked as deleted, just clear the deleting state
295
+ this.setState({ deletingMessageId: null });
296
+ } catch (error) {
297
+ console.error('Failed to delete message:', error);
298
+ // Revert the optimistic update on failure
299
+ const revertedMessages = this.state.messages.map((m) => {
300
+ if (m._id === messageToDelete._id) {
301
+ return messageToDelete;
302
+ }
303
+ return m;
304
+ });
305
+ this.setState({
306
+ messages: revertedMessages,
307
+ deletingMessageId: null,
308
+ });
309
+ alert('Failed to delete message. Please try again.');
310
+ }
311
+ };
312
+
313
+ onCancelDelete = () => {
314
+ this.setState({
315
+ showDeleteConfirm: false,
316
+ messageToDelete: null,
317
+ });
318
+ };
319
+
259
320
  sendMessage = () => {
260
321
  const message = {
261
322
  _id: Helper.randomString(),
@@ -397,8 +458,11 @@ class Circle extends Component {
397
458
  );
398
459
  }
399
460
  const isSelf = m.user._id === this.props.user.Id;
461
+ const isDeleted = m.deleted === true;
462
+ const isDeleting = this.state.deletingMessageId === m._id;
463
+
400
464
  return (
401
- <div key={m._id} className={`message${isSelf ? ' message-self' : ''}${m.uploading ? ' message-uploading' : ''}`}>
465
+ <div key={m._id} className={`message${isSelf ? ' message-self' : ''}${m.uploading ? ' message-uploading' : ''}${isDeleting ? ' message-deleting' : ''}`}>
402
466
  <Components.Text type="h5-noUpper" className="message_time">
403
467
  {moment.utc(m.createdAt).local().format('D MMM YYYY • h:mma')}
404
468
  </Components.Text>
@@ -407,9 +471,9 @@ class Circle extends Component {
407
471
  <div className="message_bubbleContainer">
408
472
  <Components.Text type="body" className="message_name">
409
473
  {m.user.name}
410
- {m.replyingTo ? ` replied to ${m.replyingTo.user.name}` : ''}
474
+ {m.replyingTo && !isDeleted ? ` replied to ${m.replyingTo.user.name}` : ''}
411
475
  </Components.Text>
412
- {m.replyingTo && (
476
+ {m.replyingTo && !isDeleted && (
413
477
  <div className="message_replyBubble">
414
478
  <Components.Text type="body" className="message_text">
415
479
  {Helper.toParagraphed((m.replyingTo.text || '').substr(0, 100))}
@@ -418,33 +482,49 @@ class Circle extends Component {
418
482
  )}
419
483
  <div className="message_bubble">
420
484
  <Components.Text type="body" className="message_text">
421
- {Helper.toParagraphed(m.text)}
422
- </Components.Text>
423
- <div>
424
- {(m.image || []).map((url, i) => {
425
- return (
426
- <a href={url} target="_blank" key={i}>
427
- <img className="message_image" src={url} alt={Helper.getFileName(url)} />
428
- </a>
429
- );
430
- })}
431
- </div>
432
- <div>
433
- {(m.attachments || []).map((url, i) => {
434
- return <Components.Attachment source={url} key={i} white={isSelf} />;
435
- })}
436
- </div>
437
- </div>
438
- <div className="message_reply">
439
- <Components.Text
440
- type="button"
441
- onClick={() => {
442
- this.onReply(m);
443
- }}
444
- >
445
- Reply
485
+ {isDeleted ? '[Message deleted]' : Helper.toParagraphed(m.text)}
446
486
  </Components.Text>
487
+ {!isDeleted && (
488
+ <>
489
+ <div>
490
+ {(m.image || []).map((url, i) => {
491
+ return (
492
+ <a href={url} target="_blank" key={i}>
493
+ <img className="message_image" src={url} alt={Helper.getFileName(url)} />
494
+ </a>
495
+ );
496
+ })}
497
+ </div>
498
+ <div>
499
+ {(m.attachments || []).map((url, i) => {
500
+ return <Components.Attachment source={url} key={i} white={isSelf} />;
501
+ })}
502
+ </div>
503
+ </>
504
+ )}
447
505
  </div>
506
+ {!isDeleted && (
507
+ <div className="message_reply" style={{ display: 'flex', gap: '16px' }}>
508
+ <Components.Text
509
+ type="button"
510
+ onClick={() => {
511
+ this.onReply(m);
512
+ }}
513
+ >
514
+ Reply
515
+ </Components.Text>
516
+ {isSelf && (
517
+ <Components.Text
518
+ type="button"
519
+ onClick={() => {
520
+ this.onDeleteMessage(m);
521
+ }}
522
+ >
523
+ Delete
524
+ </Components.Text>
525
+ )}
526
+ </div>
527
+ )}
448
528
  </div>
449
529
  </div>
450
530
  </div>
@@ -511,7 +591,7 @@ class Circle extends Component {
511
591
  </div>
512
592
  {this.state.imagesExpanded && (
513
593
  <div className="paddingTop-8">
514
- {this.state.images.map((image, i) => {
594
+ {this.state.images.map((image) => {
515
595
  return (
516
596
  <a href={image.Url} target="_blank">
517
597
  <img src={image.Url} className="chat_section_image" alt={Helper.getFileName(image.Url)} />
@@ -571,9 +651,40 @@ class Circle extends Component {
571
651
  );
572
652
  }
573
653
 
654
+ renderDeleteConfirmPopup() {
655
+ if (!this.state.showDeleteConfirm) return null;
656
+
657
+ return (
658
+ <Components.Popup
659
+ title="Delete Message"
660
+ buttons={[
661
+ {
662
+ text: 'Delete',
663
+ onClick: this.onConfirmDelete,
664
+ type: 'primary',
665
+ isActive: true,
666
+ },
667
+ {
668
+ text: 'Cancel',
669
+ onClick: this.onCancelDelete,
670
+ type: 'tertiary',
671
+ isActive: true,
672
+ },
673
+ ]}
674
+ onClose={this.onCancelDelete}
675
+ hasPadding
676
+ >
677
+ <Components.Text type="body">
678
+ Are you sure you want to delete this message? This action cannot be undone.
679
+ </Components.Text>
680
+ </Components.Popup>
681
+ );
682
+ }
683
+
574
684
  render() {
575
685
  return (
576
686
  <Components.OverlayPage fullPage fullPageStyle={{ display: 'flex', flexDirection: 'column' }}>
687
+ {this.renderDeleteConfirmPopup()}
577
688
  <Components.Header rightContent={this.renderHeaderRight()}>
578
689
  <FontAwesome
579
690
  className="header_back"
@@ -636,8 +747,6 @@ class Circle extends Component {
636
747
  }
637
748
  }
638
749
 
639
- const styles = {};
640
-
641
750
  const mapStateToProps = (state) => {
642
751
  const { circles } = state[values.reducerKey];
643
752
  const { auth } = state;