@cloudflare/realtimekit-ui 1.1.0-staging.7 → 1.1.0-staging.8

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.
@@ -8,9 +8,9 @@ import { i as index } from './p-f47d4fe8.js';
8
8
  import { d as defineCustomElement$o } from './p-241a8245.js';
9
9
  import { d as defineCustomElement$n } from './p-1391bef0.js';
10
10
  import { d as defineCustomElement$m } from './p-a73665b4.js';
11
- import { d as defineCustomElement$l } from './p-1d16490e.js';
11
+ import { d as defineCustomElement$l } from './p-7e90e964.js';
12
12
  import { d as defineCustomElement$k } from './p-28170a8d.js';
13
- import { d as defineCustomElement$j } from './p-7be71567.js';
13
+ import { d as defineCustomElement$j } from './p-9213c3fc.js';
14
14
  import { d as defineCustomElement$i } from './p-1f5a4682.js';
15
15
  import { d as defineCustomElement$h } from './p-598dc3f2.js';
16
16
  import { d as defineCustomElement$g } from './p-0e5cc539.js';
@@ -23,7 +23,7 @@ import { d as defineCustomElement$a } from './p-2447a26f.js';
23
23
  import { d as defineCustomElement$9 } from './p-819cb785.js';
24
24
  import { d as defineCustomElement$8 } from './p-7148ec6a.js';
25
25
  import { d as defineCustomElement$7 } from './p-0f2de0f8.js';
26
- import { d as defineCustomElement$6 } from './p-7f8d9afc.js';
26
+ import { d as defineCustomElement$6 } from './p-ad8282dc.js';
27
27
  import { d as defineCustomElement$5 } from './p-4ebf9684.js';
28
28
  import { d as defineCustomElement$4 } from './p-4902c5cf.js';
29
29
  import { d as defineCustomElement$3 } from './p-6739a399.js';
@@ -1,4 +1,4 @@
1
- import { R as RtkPaginatedList$1, d as defineCustomElement$1 } from './p-7f8d9afc.js';
1
+ import { R as RtkPaginatedList$1, d as defineCustomElement$1 } from './p-ad8282dc.js';
2
2
 
3
3
  const RtkPaginatedList = RtkPaginatedList$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-01-20T04:51:21",
2
+ "timestamp": "2026-01-20T09:16:34",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.27.2",
@@ -50500,6 +50500,26 @@
50500
50500
  "docs": "Event emitted when a message is deleted",
50501
50501
  "docsTags": []
50502
50502
  },
50503
+ {
50504
+ "event": "editMessage",
50505
+ "detail": "CustomMessage | FileMessage | ImageMessage | TextMessage",
50506
+ "bubbles": true,
50507
+ "complexType": {
50508
+ "original": "Message",
50509
+ "resolved": "CustomMessage | FileMessage | ImageMessage | TextMessage",
50510
+ "references": {
50511
+ "Message": {
50512
+ "location": "import",
50513
+ "path": "@cloudflare/realtimekit",
50514
+ "id": "node_modules::Message"
50515
+ }
50516
+ }
50517
+ },
50518
+ "cancelable": true,
50519
+ "composed": true,
50520
+ "docs": "Event emitted when a message is edited",
50521
+ "docsTags": []
50522
+ },
50503
50523
  {
50504
50524
  "event": "editMessageInit",
50505
50525
  "detail": "{ payload: TextMessage; flags: { isReply?: boolean; isEdit?: boolean; }; }",
@@ -151082,15 +151102,15 @@
151082
151102
  "docs": ""
151083
151103
  },
151084
151104
  "complexType": {
151085
- "signature": "(_id: string, _node: DataNode) => Promise<void>",
151105
+ "signature": "(id: string, node: DataNode) => Promise<void>",
151086
151106
  "parameters": [
151087
151107
  {
151088
- "name": "_id",
151108
+ "name": "id",
151089
151109
  "type": "string",
151090
151110
  "docs": "- The id of the node to update"
151091
151111
  },
151092
151112
  {
151093
- "name": "_node",
151113
+ "name": "node",
151094
151114
  "type": "DataNode",
151095
151115
  "docs": "- The updated data node"
151096
151116
  }
@@ -151108,15 +151128,15 @@
151108
151128
  },
151109
151129
  "return": "Promise<void>"
151110
151130
  },
151111
- "signature": "onNodeUpdate(_id: string, _node: DataNode) => Promise<void>",
151131
+ "signature": "onNodeUpdate(id: string, node: DataNode) => Promise<void>",
151112
151132
  "parameters": [
151113
151133
  {
151114
- "name": "_id",
151134
+ "name": "id",
151115
151135
  "type": "string",
151116
151136
  "docs": "- The id of the node to update"
151117
151137
  },
151118
151138
  {
151119
- "name": "_node",
151139
+ "name": "node",
151120
151140
  "type": "DataNode",
151121
151141
  "docs": "- The updated data node"
151122
151142
  }
@@ -151125,11 +151145,11 @@
151125
151145
  "docsTags": [
151126
151146
  {
151127
151147
  "name": "param",
151128
- "text": "_id - The id of the node to update"
151148
+ "text": "id - The id of the node to update"
151129
151149
  },
151130
151150
  {
151131
151151
  "name": "param",
151132
- "text": "_node - The updated data node"
151152
+ "text": "node - The updated data node"
151133
151153
  }
151134
151154
  ]
151135
151155
  }
@@ -11045,6 +11045,13 @@ const RtkChat = class {
11045
11045
  const message = event.detail;
11046
11046
  this.meeting.chat.deleteMessage(message.id);
11047
11047
  };
11048
+ this.onMessageEdit = (event) => {
11049
+ const message = event.detail;
11050
+ if (message.type !== 'text')
11051
+ return;
11052
+ this.replyMessage = null;
11053
+ this.editingMessage = message;
11054
+ };
11048
11055
  this.getPrivateChatRecipients = () => {
11049
11056
  const participants = this.getFilteredParticipants().map((participant) => {
11050
11057
  const key = generateChatGroupKey([participant.userId, this.meeting.self.userId]);
@@ -11229,14 +11236,21 @@ const RtkChat = class {
11229
11236
  const uiProps = { iconPack: this.iconPack, t: this.t, size: this.size };
11230
11237
  const message = this.editingMessage ? this.editingMessage.message : '';
11231
11238
  const quotedMessage = this.replyMessage ? this.replyMessage.message : '';
11232
- return (h("rtk-chat-composer-view", Object.assign({ message: message, storageKey: (_a = this.selectedChannelId) !== null && _a !== void 0 ? _a : `draft-${this.selectedChannelId}`, quotedMessage: quotedMessage, isEditing: !!this.editingMessage, canSendTextMessage: this.isTextMessagingAllowed(), canSendFiles: this.isFileMessagingAllowed(), disableEmojiPicker: this.overrides.disableEmojiPicker, maxLength: this.meeting.chat.maxTextLimit, rateLimits: this.meeting.chat.rateLimits, inputTextPlaceholder: this.t('chat.message_placeholder'), onNewMessage: this.onNewMessageHandler, onEditMessage: this.onEditMessageHandler, onEditCancel: this.onEditCancel, onQuotedMessageDismiss: this.onQuotedMessageDismiss }, uiProps), h("slot", { name: "chat-addon", slot: "chat-addon" })));
11239
+ const draftStorageKey = this.selectedChannelId
11240
+ ? `rtk-chat-draft-${this.selectedChannelId}`
11241
+ : 'rtk-chat-draft';
11242
+ const editStorageKey = this.editingMessage
11243
+ ? `rtk-chat-edit-${(_a = this.selectedChannelId) !== null && _a !== void 0 ? _a : 'no-channel'}-${this.editingMessage.id}`
11244
+ : 'rtk-chat-edit';
11245
+ const storageKey = this.editingMessage ? editStorageKey : draftStorageKey;
11246
+ return (h("rtk-chat-composer-view", Object.assign({ message: message, storageKey: storageKey, quotedMessage: quotedMessage, isEditing: !!this.editingMessage, canSendTextMessage: this.isTextMessagingAllowed(), canSendFiles: this.isFileMessagingAllowed(), disableEmojiPicker: this.overrides.disableEmojiPicker, maxLength: this.meeting.chat.maxTextLimit, rateLimits: this.meeting.chat.rateLimits, inputTextPlaceholder: this.t('chat.message_placeholder'), onNewMessage: this.onNewMessageHandler, onEditMessage: this.onEditMessageHandler, onEditCancel: this.onEditCancel, onQuotedMessageDismiss: this.onQuotedMessageDismiss }, uiProps), h("slot", { name: "chat-addon", slot: "chat-addon" })));
11233
11247
  }
11234
11248
  render() {
11235
11249
  var _a;
11236
11250
  if (!this.meeting) {
11237
11251
  return null;
11238
11252
  }
11239
- return (h(Host, null, h("div", { class: "chat-container" }, h("div", { class: "chat" }, this.isFileMessagingAllowed() && (h("div", { id: "dropzone", class: { active: this.dropzoneActivated }, part: "dropzone" }, h("rtk-icon", { icon: this.iconPack.attach }), h("p", null, this.t('chat.send_attachment')))), this.renderPinnedMessagesHeader(), this.isPrivateChatSupported() && (h("rtk-channel-selector-view", { channels: this.getPrivateChatRecipients(), selectedChannelId: ((_a = this.selectedParticipant) === null || _a === void 0 ? void 0 : _a.userId) || 'everyone', onChannelChange: this.updateRecipients, t: this.t, viewAs: "dropdown" })), h("rtk-chat-messages-ui-paginated", { meeting: this.meeting, onPinMessage: this.onPinMessage, onDeleteMessage: this.onDeleteMessage, size: this.size, iconPack: this.iconPack, t: this.t }), this.renderComposerUI()))));
11253
+ return (h(Host, null, h("div", { class: "chat-container" }, h("div", { class: "chat" }, this.isFileMessagingAllowed() && (h("div", { id: "dropzone", class: { active: this.dropzoneActivated }, part: "dropzone" }, h("rtk-icon", { icon: this.iconPack.attach }), h("p", null, this.t('chat.send_attachment')))), this.renderPinnedMessagesHeader(), this.isPrivateChatSupported() && (h("rtk-channel-selector-view", { channels: this.getPrivateChatRecipients(), selectedChannelId: ((_a = this.selectedParticipant) === null || _a === void 0 ? void 0 : _a.userId) || 'everyone', onChannelChange: this.updateRecipients, t: this.t, viewAs: "dropdown" })), h("rtk-chat-messages-ui-paginated", { meeting: this.meeting, onPinMessage: this.onPinMessage, onEditMessage: this.onMessageEdit, onDeleteMessage: this.onDeleteMessage, size: this.size, iconPack: this.iconPack, t: this.t }), this.renderComposerUI()))));
11240
11254
  }
11241
11255
  get host() { return getElement(this); }
11242
11256
  static get watchers() { return {
@@ -11479,6 +11493,7 @@ const RtkChatMessagesUiPaginated = class {
11479
11493
  registerInstance(this, hostRef);
11480
11494
  this.editMessageInit = createEvent(this, "editMessageInit", 7);
11481
11495
  this.onPinMessage = createEvent(this, "pinMessage", 7);
11496
+ this.onEditMessage = createEvent(this, "editMessage", 7);
11482
11497
  this.onDeleteMessage = createEvent(this, "deleteMessage", 7);
11483
11498
  this.stateUpdate = createEvent(this, "rtkStateUpdate", 7);
11484
11499
  /** Icon pack */
@@ -11529,22 +11544,18 @@ const RtkChatMessagesUiPaginated = class {
11529
11544
  };
11530
11545
  this.getMessageActions = (message) => {
11531
11546
  const actions = [];
11532
- // const isSelf = this.meeting.self.userId === message.userId;
11533
- // const chatMessagePermissions = this.meeting.self.permissions?.chatMessage;
11534
- // const canEdit =
11535
- // chatMessagePermissions === undefined
11536
- // ? isSelf
11537
- // : chatMessagePermissions.canEdit === 'ALL' ||
11538
- // (chatMessagePermissions.canEdit === 'SELF' && isSelf);
11539
- const canDelete = message.userId === this.meeting.self.userId;
11540
- if (this.meeting.self.permissions.pinParticipant) {
11547
+ const messageBelongsToSelf = message.userId === this.meeting.self.userId;
11548
+ actions.push({
11549
+ id: 'pin_message',
11550
+ label: message.pinned ? this.t('unpin') : this.t('pin'),
11551
+ icon: this.iconPack.pin,
11552
+ });
11553
+ if (messageBelongsToSelf) {
11541
11554
  actions.push({
11542
- id: 'pin_message',
11543
- label: message.pinned ? this.t('unpin') : this.t('pin'),
11544
- icon: this.iconPack.pin,
11555
+ id: 'edit_message',
11556
+ label: this.t('chat.edit_msg'),
11557
+ icon: this.iconPack.edit,
11545
11558
  });
11546
- }
11547
- if (canDelete) {
11548
11559
  actions.push({
11549
11560
  id: 'delete_message',
11550
11561
  label: this.t('chat.delete_msg'),
@@ -11558,6 +11569,9 @@ const RtkChatMessagesUiPaginated = class {
11558
11569
  case 'pin_message':
11559
11570
  this.onPinMessage.emit(message);
11560
11571
  break;
11572
+ case 'edit_message':
11573
+ this.onEditMessage.emit(message);
11574
+ break;
11561
11575
  case 'delete_message':
11562
11576
  this.onDeleteMessage.emit(message);
11563
11577
  break;
@@ -11634,7 +11648,7 @@ const RtkChatMessagesUiPaginated = class {
11634
11648
  this.lastReadMessageIndex = -1;
11635
11649
  }
11636
11650
  render() {
11637
- return (h(Host, { key: 'c710da6e2fda420146905a2ed75d3444dd6d2c0b' }, h("rtk-paginated-list", { key: '51a36437e38e9c0242cca34bfda39f6d8309bee3', ref: (el) => (this.$paginatedListRef = el), pageSize: this.pageSize, pagesAllowed: 3, fetchData: this.getChatMessages, createNodes: this.createChatNodes, selectedItemId: this.selectedChannelId, emptyListLabel: this.t('chat.empty_channel') }, h("slot", { key: '69b54a41263510b425ce3e39af055321c4e2deb8' }))));
11651
+ return (h(Host, { key: '55b594d1fad2c164a70b71e297f63273ece0bc4f' }, h("rtk-paginated-list", { key: '1554ee896643feec72a02672f156f95c988813ce', ref: (el) => (this.$paginatedListRef = el), pageSize: this.pageSize, pagesAllowed: 3, fetchData: this.getChatMessages, createNodes: this.createChatNodes, selectedItemId: this.selectedChannelId, emptyListLabel: this.t('chat.empty_channel') }, h("slot", { key: '03aeb2069b87cb217b9759cabd3835c9bac81f11' }))));
11638
11652
  }
11639
11653
  get host() { return getElement(this); }
11640
11654
  static get watchers() { return {
@@ -12662,7 +12676,8 @@ const RtkPaginatedList = class {
12662
12676
  this.oldTS = node.timeMs + 1;
12663
12677
  this.loadPrevPage();
12664
12678
  }
12665
- else {
12679
+ else if (this.maxTS === this.newTS) {
12680
+ this.maxTS = node.timeMs;
12666
12681
  // append messages to the page if page has not reached full capacity
12667
12682
  if (this.pages[0].length < this.pageSize) {
12668
12683
  this.pages[0].unshift(node);
@@ -12711,10 +12726,21 @@ const RtkPaginatedList = class {
12711
12726
  }
12712
12727
  /**
12713
12728
  * Updates a new node anywhere in the list
12714
- * @param {string} _id - The id of the node to update
12715
- * @param {DataNode} _node - The updated data node
12729
+ * @param {string} id - The id of the node to update
12730
+ * @param {DataNode} node - The updated data node
12716
12731
  * */
12717
- async onNodeUpdate(_id, _node) { }
12732
+ async onNodeUpdate(id, node) {
12733
+ for (let i = this.pages.length - 1; i >= 0; i--) {
12734
+ const index = this.pages[i].findIndex((node) => node.id === id);
12735
+ // if message not found, move on
12736
+ if (index === -1)
12737
+ continue;
12738
+ // edit message
12739
+ this.pages[i][index] = node;
12740
+ this.rerender();
12741
+ break;
12742
+ }
12743
+ }
12718
12744
  connectedCallback() {
12719
12745
  this.rerender = debounce$1(this.rerender.bind(this), 50, { maxWait: 200 });
12720
12746
  }
@@ -12765,6 +12791,8 @@ const RtkPaginatedList = class {
12765
12791
  const lastPage = this.pages[this.pages.length - 1];
12766
12792
  this.oldTS = lastPage[lastPage.length - 1].timeMs;
12767
12793
  this.newTS = this.pages[0][0].timeMs;
12794
+ if (!this.maxTS)
12795
+ this.maxTS = this.newTS;
12768
12796
  this.rerender();
12769
12797
  // fix scroll position
12770
12798
  if (scrollAnchor)
@@ -12792,6 +12820,7 @@ const RtkPaginatedList = class {
12792
12820
  this.isLoadingBottom = false;
12793
12821
  // no more new messages to load
12794
12822
  if (!data.length) {
12823
+ this.maxTS = this.newTS;
12795
12824
  this.showNewMessagesCTR = false;
12796
12825
  this.shouldScrollToBottom = false;
12797
12826
  break;
@@ -12887,10 +12916,10 @@ const RtkPaginatedList = class {
12887
12916
  /**
12888
12917
  * div.container is flex=column-reversewhich is why div#bottom-scroll comes before div#top-scroll
12889
12918
  */
12890
- return (h(Host, { key: 'e0f806cccdcba162d0c834476863b34630cb1a1e' }, h("div", { key: '6d54d50ed703a59df8d26399499533e3cb0d70fe', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '4e9fcbed725fb55d9fbb67eca94b0e770662d51b', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: '7db0236d35db3fb9856fea7a4f62c1fbd421829e', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
12919
+ return (h(Host, { key: '5f036ac16ace127734d5ee172d537c64baeab415' }, h("div", { key: 'b6d8cf3019a72350f7a3a5b4d020b6ab39793f53', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '5c63462ffd995a3e266652bba4e3377636c5f9ca', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: 'c1fc4f2759d5be662047245b0dae3eb6f65a9b50', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
12891
12920
  this.shouldScrollToBottom = true;
12892
12921
  this.scrollToBottom();
12893
- } }, h("rtk-icon", { key: '6e247e86029560601080e0b4d6dcfccbd90fcdd6', icon: this.iconPack.chevron_down }))), h("div", { key: '01d1ba7eacc67ece70b805fb2dfb493cdf1c9d23', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: '24391bfc34914675cbfd0c287332bfdf3f5f5000', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: 'e6c2cb44fce52ca54c9f1e543d91a29648745408', size: "lg" }), !this.isLoading && this.pages.flat().length === 0 ? (h("div", { class: "empty-list" }, this.t('list.empty'))) : (h("div", { class: "page-wrapper" }, this.pages.map((page, pageIndex) => (h("div", { class: "page", "data-page-index": pageIndex }, this.createNodes([...page].reverse())))))), this.isLoadingTop && this.pages.length > 0 && h("rtk-spinner", { key: 'd90a15494bcd7ec6c9c7ffc5e9a55054252a4258', size: "sm" }), h("div", { key: '2a65f98c3c4e6f2510c6cf1b4e2bcf1e607a7552', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
12922
+ } }, h("rtk-icon", { key: '96b19395a2ca8e87ca5004f675cf79f8d58f036c', icon: this.iconPack.chevron_down }))), h("div", { key: '84789a3d0fa4645be711a87cda1e109e4f7d0db2', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: 'd17f28cc01695220ed6e705d528e8f555b77e8ea', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: '4ee308d335cdc1f86e2bfdcc20611f50a51ef816', size: "lg" }), !this.isLoading && this.pages.flat().length === 0 ? (h("div", { class: "empty-list" }, this.t('list.empty'))) : (h("div", { class: "page-wrapper" }, this.pages.map((page, pageIndex) => (h("div", { class: "page", "data-page-index": pageIndex }, this.createNodes([...page].reverse())))))), this.isLoadingTop && this.pages.length > 0 && h("rtk-spinner", { key: 'c07c4dd4c4ed0adf01d2fc224b7196a0f86243fd', size: "sm" }), h("div", { key: '52161ac30062c2262f1cdbcded50f2716f6ed20e', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
12894
12923
  }
12895
12924
  };
12896
12925
  __decorate$2$8([
@@ -503,6 +503,13 @@ const RtkChat = class {
503
503
  const message = event.detail;
504
504
  this.meeting.chat.deleteMessage(message.id);
505
505
  };
506
+ this.onMessageEdit = (event) => {
507
+ const message = event.detail;
508
+ if (message.type !== 'text')
509
+ return;
510
+ this.replyMessage = null;
511
+ this.editingMessage = message;
512
+ };
506
513
  this.getPrivateChatRecipients = () => {
507
514
  const participants = this.getFilteredParticipants().map((participant) => {
508
515
  const key = generateChatGroupKey([participant.userId, this.meeting.self.userId]);
@@ -687,14 +694,21 @@ const RtkChat = class {
687
694
  const uiProps = { iconPack: this.iconPack, t: this.t, size: this.size };
688
695
  const message = this.editingMessage ? this.editingMessage.message : '';
689
696
  const quotedMessage = this.replyMessage ? this.replyMessage.message : '';
690
- return (h("rtk-chat-composer-view", Object.assign({ message: message, storageKey: (_a = this.selectedChannelId) !== null && _a !== void 0 ? _a : `draft-${this.selectedChannelId}`, quotedMessage: quotedMessage, isEditing: !!this.editingMessage, canSendTextMessage: this.isTextMessagingAllowed(), canSendFiles: this.isFileMessagingAllowed(), disableEmojiPicker: this.overrides.disableEmojiPicker, maxLength: this.meeting.chat.maxTextLimit, rateLimits: this.meeting.chat.rateLimits, inputTextPlaceholder: this.t('chat.message_placeholder'), onNewMessage: this.onNewMessageHandler, onEditMessage: this.onEditMessageHandler, onEditCancel: this.onEditCancel, onQuotedMessageDismiss: this.onQuotedMessageDismiss }, uiProps), h("slot", { name: "chat-addon", slot: "chat-addon" })));
697
+ const draftStorageKey = this.selectedChannelId
698
+ ? `rtk-chat-draft-${this.selectedChannelId}`
699
+ : 'rtk-chat-draft';
700
+ const editStorageKey = this.editingMessage
701
+ ? `rtk-chat-edit-${(_a = this.selectedChannelId) !== null && _a !== void 0 ? _a : 'no-channel'}-${this.editingMessage.id}`
702
+ : 'rtk-chat-edit';
703
+ const storageKey = this.editingMessage ? editStorageKey : draftStorageKey;
704
+ return (h("rtk-chat-composer-view", Object.assign({ message: message, storageKey: storageKey, quotedMessage: quotedMessage, isEditing: !!this.editingMessage, canSendTextMessage: this.isTextMessagingAllowed(), canSendFiles: this.isFileMessagingAllowed(), disableEmojiPicker: this.overrides.disableEmojiPicker, maxLength: this.meeting.chat.maxTextLimit, rateLimits: this.meeting.chat.rateLimits, inputTextPlaceholder: this.t('chat.message_placeholder'), onNewMessage: this.onNewMessageHandler, onEditMessage: this.onEditMessageHandler, onEditCancel: this.onEditCancel, onQuotedMessageDismiss: this.onQuotedMessageDismiss }, uiProps), h("slot", { name: "chat-addon", slot: "chat-addon" })));
691
705
  }
692
706
  render() {
693
707
  var _a;
694
708
  if (!this.meeting) {
695
709
  return null;
696
710
  }
697
- return (h(Host, null, h("div", { class: "chat-container" }, h("div", { class: "chat" }, this.isFileMessagingAllowed() && (h("div", { id: "dropzone", class: { active: this.dropzoneActivated }, part: "dropzone" }, h("rtk-icon", { icon: this.iconPack.attach }), h("p", null, this.t('chat.send_attachment')))), this.renderPinnedMessagesHeader(), this.isPrivateChatSupported() && (h("rtk-channel-selector-view", { channels: this.getPrivateChatRecipients(), selectedChannelId: ((_a = this.selectedParticipant) === null || _a === void 0 ? void 0 : _a.userId) || 'everyone', onChannelChange: this.updateRecipients, t: this.t, viewAs: "dropdown" })), h("rtk-chat-messages-ui-paginated", { meeting: this.meeting, onPinMessage: this.onPinMessage, onDeleteMessage: this.onDeleteMessage, size: this.size, iconPack: this.iconPack, t: this.t }), this.renderComposerUI()))));
711
+ return (h(Host, null, h("div", { class: "chat-container" }, h("div", { class: "chat" }, this.isFileMessagingAllowed() && (h("div", { id: "dropzone", class: { active: this.dropzoneActivated }, part: "dropzone" }, h("rtk-icon", { icon: this.iconPack.attach }), h("p", null, this.t('chat.send_attachment')))), this.renderPinnedMessagesHeader(), this.isPrivateChatSupported() && (h("rtk-channel-selector-view", { channels: this.getPrivateChatRecipients(), selectedChannelId: ((_a = this.selectedParticipant) === null || _a === void 0 ? void 0 : _a.userId) || 'everyone', onChannelChange: this.updateRecipients, t: this.t, viewAs: "dropdown" })), h("rtk-chat-messages-ui-paginated", { meeting: this.meeting, onPinMessage: this.onPinMessage, onEditMessage: this.onMessageEdit, onDeleteMessage: this.onDeleteMessage, size: this.size, iconPack: this.iconPack, t: this.t }), this.renderComposerUI()))));
698
712
  }
699
713
  get host() { return getElement(this); }
700
714
  static get watchers() { return {
@@ -937,6 +951,7 @@ const RtkChatMessagesUiPaginated = class {
937
951
  registerInstance(this, hostRef);
938
952
  this.editMessageInit = createEvent(this, "editMessageInit", 7);
939
953
  this.onPinMessage = createEvent(this, "pinMessage", 7);
954
+ this.onEditMessage = createEvent(this, "editMessage", 7);
940
955
  this.onDeleteMessage = createEvent(this, "deleteMessage", 7);
941
956
  this.stateUpdate = createEvent(this, "rtkStateUpdate", 7);
942
957
  /** Icon pack */
@@ -987,22 +1002,18 @@ const RtkChatMessagesUiPaginated = class {
987
1002
  };
988
1003
  this.getMessageActions = (message) => {
989
1004
  const actions = [];
990
- // const isSelf = this.meeting.self.userId === message.userId;
991
- // const chatMessagePermissions = this.meeting.self.permissions?.chatMessage;
992
- // const canEdit =
993
- // chatMessagePermissions === undefined
994
- // ? isSelf
995
- // : chatMessagePermissions.canEdit === 'ALL' ||
996
- // (chatMessagePermissions.canEdit === 'SELF' && isSelf);
997
- const canDelete = message.userId === this.meeting.self.userId;
998
- if (this.meeting.self.permissions.pinParticipant) {
1005
+ const messageBelongsToSelf = message.userId === this.meeting.self.userId;
1006
+ actions.push({
1007
+ id: 'pin_message',
1008
+ label: message.pinned ? this.t('unpin') : this.t('pin'),
1009
+ icon: this.iconPack.pin,
1010
+ });
1011
+ if (messageBelongsToSelf) {
999
1012
  actions.push({
1000
- id: 'pin_message',
1001
- label: message.pinned ? this.t('unpin') : this.t('pin'),
1002
- icon: this.iconPack.pin,
1013
+ id: 'edit_message',
1014
+ label: this.t('chat.edit_msg'),
1015
+ icon: this.iconPack.edit,
1003
1016
  });
1004
- }
1005
- if (canDelete) {
1006
1017
  actions.push({
1007
1018
  id: 'delete_message',
1008
1019
  label: this.t('chat.delete_msg'),
@@ -1016,6 +1027,9 @@ const RtkChatMessagesUiPaginated = class {
1016
1027
  case 'pin_message':
1017
1028
  this.onPinMessage.emit(message);
1018
1029
  break;
1030
+ case 'edit_message':
1031
+ this.onEditMessage.emit(message);
1032
+ break;
1019
1033
  case 'delete_message':
1020
1034
  this.onDeleteMessage.emit(message);
1021
1035
  break;
@@ -1092,7 +1106,7 @@ const RtkChatMessagesUiPaginated = class {
1092
1106
  this.lastReadMessageIndex = -1;
1093
1107
  }
1094
1108
  render() {
1095
- return (h(Host, { key: 'c710da6e2fda420146905a2ed75d3444dd6d2c0b' }, h("rtk-paginated-list", { key: '51a36437e38e9c0242cca34bfda39f6d8309bee3', ref: (el) => (this.$paginatedListRef = el), pageSize: this.pageSize, pagesAllowed: 3, fetchData: this.getChatMessages, createNodes: this.createChatNodes, selectedItemId: this.selectedChannelId, emptyListLabel: this.t('chat.empty_channel') }, h("slot", { key: '69b54a41263510b425ce3e39af055321c4e2deb8' }))));
1109
+ return (h(Host, { key: '55b594d1fad2c164a70b71e297f63273ece0bc4f' }, h("rtk-paginated-list", { key: '1554ee896643feec72a02672f156f95c988813ce', ref: (el) => (this.$paginatedListRef = el), pageSize: this.pageSize, pagesAllowed: 3, fetchData: this.getChatMessages, createNodes: this.createChatNodes, selectedItemId: this.selectedChannelId, emptyListLabel: this.t('chat.empty_channel') }, h("slot", { key: '03aeb2069b87cb217b9759cabd3835c9bac81f11' }))));
1096
1110
  }
1097
1111
  get host() { return getElement(this); }
1098
1112
  static get watchers() { return {
@@ -2126,7 +2140,8 @@ const RtkPaginatedList = class {
2126
2140
  this.oldTS = node.timeMs + 1;
2127
2141
  this.loadPrevPage();
2128
2142
  }
2129
- else {
2143
+ else if (this.maxTS === this.newTS) {
2144
+ this.maxTS = node.timeMs;
2130
2145
  // append messages to the page if page has not reached full capacity
2131
2146
  if (this.pages[0].length < this.pageSize) {
2132
2147
  this.pages[0].unshift(node);
@@ -2175,10 +2190,21 @@ const RtkPaginatedList = class {
2175
2190
  }
2176
2191
  /**
2177
2192
  * Updates a new node anywhere in the list
2178
- * @param {string} _id - The id of the node to update
2179
- * @param {DataNode} _node - The updated data node
2193
+ * @param {string} id - The id of the node to update
2194
+ * @param {DataNode} node - The updated data node
2180
2195
  * */
2181
- async onNodeUpdate(_id, _node) { }
2196
+ async onNodeUpdate(id, node) {
2197
+ for (let i = this.pages.length - 1; i >= 0; i--) {
2198
+ const index = this.pages[i].findIndex((node) => node.id === id);
2199
+ // if message not found, move on
2200
+ if (index === -1)
2201
+ continue;
2202
+ // edit message
2203
+ this.pages[i][index] = node;
2204
+ this.rerender();
2205
+ break;
2206
+ }
2207
+ }
2182
2208
  connectedCallback() {
2183
2209
  this.rerender = debounce(this.rerender.bind(this), 50, { maxWait: 200 });
2184
2210
  }
@@ -2229,6 +2255,8 @@ const RtkPaginatedList = class {
2229
2255
  const lastPage = this.pages[this.pages.length - 1];
2230
2256
  this.oldTS = lastPage[lastPage.length - 1].timeMs;
2231
2257
  this.newTS = this.pages[0][0].timeMs;
2258
+ if (!this.maxTS)
2259
+ this.maxTS = this.newTS;
2232
2260
  this.rerender();
2233
2261
  // fix scroll position
2234
2262
  if (scrollAnchor)
@@ -2256,6 +2284,7 @@ const RtkPaginatedList = class {
2256
2284
  this.isLoadingBottom = false;
2257
2285
  // no more new messages to load
2258
2286
  if (!data.length) {
2287
+ this.maxTS = this.newTS;
2259
2288
  this.showNewMessagesCTR = false;
2260
2289
  this.shouldScrollToBottom = false;
2261
2290
  break;
@@ -2351,10 +2380,10 @@ const RtkPaginatedList = class {
2351
2380
  /**
2352
2381
  * div.container is flex=column-reversewhich is why div#bottom-scroll comes before div#top-scroll
2353
2382
  */
2354
- return (h(Host, { key: 'e0f806cccdcba162d0c834476863b34630cb1a1e' }, h("div", { key: '6d54d50ed703a59df8d26399499533e3cb0d70fe', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '4e9fcbed725fb55d9fbb67eca94b0e770662d51b', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: '7db0236d35db3fb9856fea7a4f62c1fbd421829e', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
2383
+ return (h(Host, { key: '5f036ac16ace127734d5ee172d537c64baeab415' }, h("div", { key: 'b6d8cf3019a72350f7a3a5b4d020b6ab39793f53', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '5c63462ffd995a3e266652bba4e3377636c5f9ca', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: 'c1fc4f2759d5be662047245b0dae3eb6f65a9b50', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
2355
2384
  this.shouldScrollToBottom = true;
2356
2385
  this.scrollToBottom();
2357
- } }, h("rtk-icon", { key: '6e247e86029560601080e0b4d6dcfccbd90fcdd6', icon: this.iconPack.chevron_down }))), h("div", { key: '01d1ba7eacc67ece70b805fb2dfb493cdf1c9d23', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: '24391bfc34914675cbfd0c287332bfdf3f5f5000', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: 'e6c2cb44fce52ca54c9f1e543d91a29648745408', size: "lg" }), !this.isLoading && this.pages.flat().length === 0 ? (h("div", { class: "empty-list" }, this.t('list.empty'))) : (h("div", { class: "page-wrapper" }, this.pages.map((page, pageIndex) => (h("div", { class: "page", "data-page-index": pageIndex }, this.createNodes([...page].reverse())))))), this.isLoadingTop && this.pages.length > 0 && h("rtk-spinner", { key: 'd90a15494bcd7ec6c9c7ffc5e9a55054252a4258', size: "sm" }), h("div", { key: '2a65f98c3c4e6f2510c6cf1b4e2bcf1e607a7552', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
2386
+ } }, h("rtk-icon", { key: '96b19395a2ca8e87ca5004f675cf79f8d58f036c', icon: this.iconPack.chevron_down }))), h("div", { key: '84789a3d0fa4645be711a87cda1e109e4f7d0db2', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: 'd17f28cc01695220ed6e705d528e8f555b77e8ea', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: '4ee308d335cdc1f86e2bfdcc20611f50a51ef816', size: "lg" }), !this.isLoading && this.pages.flat().length === 0 ? (h("div", { class: "empty-list" }, this.t('list.empty'))) : (h("div", { class: "page-wrapper" }, this.pages.map((page, pageIndex) => (h("div", { class: "page", "data-page-index": pageIndex }, this.createNodes([...page].reverse())))))), this.isLoadingTop && this.pages.length > 0 && h("rtk-spinner", { key: 'c07c4dd4c4ed0adf01d2fc224b7196a0f86243fd', size: "sm" }), h("div", { key: '52161ac30062c2262f1cdbcded50f2716f6ed20e', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
2358
2387
  }
2359
2388
  };
2360
2389
  __decorate$2([