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

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.
@@ -79,10 +79,15 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
79
79
  * @param {DataNode} node - The data node to add to the beginning of the list
80
80
  */
81
81
  async onNewNode(node) {
82
- // if there are no pages, load the first page
82
+ // if there are no pages, append to the first page
83
83
  if (this.pages.length < 1) {
84
- this.oldTS = node.timeMs + 1;
85
- this.loadPrevPage();
84
+ this.oldTS = node.timeMs;
85
+ this.pages.unshift([node]);
86
+ this.newTS = node.timeMs;
87
+ this.maxTS = node.timeMs;
88
+ this.rerender();
89
+ if (this.autoScroll)
90
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
86
91
  }
87
92
  else if (this.maxTS === this.newTS) {
88
93
  this.maxTS = node.timeMs;
@@ -94,14 +99,25 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
94
99
  }
95
100
  else {
96
101
  // if page is at full capacity, load next page
97
- this.loadNextPage();
102
+ this.pages.unshift([node]);
103
+ this.newTS = node.timeMs;
104
+ // remove pages if out of bounds
105
+ if (this.pages.length > this.pagesAllowed)
106
+ this.pages.pop();
107
+ // update timestamps
108
+ const lastPage = this.pages[this.pages.length - 1];
109
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
110
+ this.newTS = this.pages[0][0].timeMs;
111
+ this.rerender();
98
112
  }
113
+ if (this.autoScroll)
114
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
99
115
  }
100
- // If autoscroll is enabled, scroll to the bottom
101
- if (this.autoScroll) {
102
- this.shouldScrollToBottom = true;
103
- this.scrollToBottom();
116
+ else {
117
+ if (this.autoScroll)
118
+ this.scrollToBottom();
104
119
  }
120
+ this.pendingScrollAnchor = null;
105
121
  }
106
122
  /**
107
123
  * Deletes a node anywhere from the list
@@ -109,7 +125,6 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
109
125
  * */
110
126
  async onNodeDelete(id) {
111
127
  var _a, _b;
112
- let didDelete = false;
113
128
  for (let i = this.pages.length - 1; i >= 0; i--) {
114
129
  const index = this.pages[i].findIndex((node) => node.id === id);
115
130
  // if message not found, move on
@@ -120,17 +135,17 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
120
135
  // if page is empty, delete it
121
136
  if (this.pages[i].length === 0)
122
137
  this.pages.splice(i, 1);
123
- didDelete = true;
138
+ // update timestamps
139
+ const firstPage = this.pages[0];
140
+ const lastPage = this.pages[this.pages.length - 1];
141
+ this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
142
+ this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
143
+ // if I have deleted the latest message, update maxTS
144
+ if (index === 0 && i === 0)
145
+ this.maxTS = this.newTS;
146
+ this.rerender();
124
147
  break;
125
148
  }
126
- if (!didDelete)
127
- return;
128
- // update timestamps
129
- const firstPage = this.pages[0];
130
- const lastPage = this.pages[this.pages.length - 1];
131
- this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
132
- this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
133
- this.rerender();
134
149
  }
135
150
  /**
136
151
  * Updates a new node anywhere in the list
@@ -157,6 +172,10 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
157
172
  this.loadPrevPage();
158
173
  if (this.$containerRef) {
159
174
  this.$containerRef.onscrollend = async () => {
175
+ // do not do anything if we are scrolling to bottom
176
+ if (this.shouldScrollToBottom)
177
+ return;
178
+ // handle top and bottom scroll
160
179
  if (this.isInView(this.$bottomRef)) {
161
180
  await this.loadNextPage();
162
181
  }
@@ -208,54 +227,47 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
208
227
  }
209
228
  async loadNextPage() {
210
229
  if (this.isLoading)
211
- return;
230
+ return [];
212
231
  // Do nothing. New timestamp needs to be assigned by loadPrevPage method
213
232
  if (!this.newTS) {
214
233
  this.showNewMessagesCTR = false;
215
- this.shouldScrollToBottom = false;
216
- return;
234
+ return [];
217
235
  }
218
- // for autoscroll or scroll to bottom button
219
- const maxAutoLoads = 200;
220
- let loads = 0;
221
- let prevNewTS = this.newTS;
222
236
  this.isLoading = true;
223
237
  this.isLoadingBottom = true;
224
- while (loads < maxAutoLoads) {
225
- const scrollAnchor = this.getScrollAnchor('bottom');
226
- const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
227
- this.isLoading = false;
228
- this.isLoadingBottom = false;
229
- // no more new messages to load
230
- if (!data.length) {
231
- this.maxTS = this.newTS;
232
- this.showNewMessagesCTR = false;
233
- this.shouldScrollToBottom = false;
234
- break;
235
- }
236
- // load new messages and append to the start
237
- this.pages.unshift(data.reverse());
238
- // remove pages if out of bounds
239
- if (this.pages.length > this.pagesAllowed)
240
- this.pages.pop();
241
- // update timestamps
242
- const lastPage = this.pages[this.pages.length - 1];
243
- this.oldTS = lastPage[lastPage.length - 1].timeMs;
244
- this.newTS = this.pages[0][0].timeMs;
245
- this.rerender();
246
- this.pendingScrollAnchor = scrollAnchor;
247
- if (!this.shouldScrollToBottom)
248
- break;
249
- // if should scroll to bottom then retrigger
250
- await this.waitForNextFrame();
251
- this.scrollToBottom();
252
- await this.waitForNextFrame();
253
- // if no new messages, break
254
- if (this.newTS === prevNewTS)
255
- break;
256
- prevNewTS = this.newTS;
257
- loads++;
238
+ const scrollAnchor = this.getScrollAnchor('bottom');
239
+ const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
240
+ this.isLoading = false;
241
+ this.isLoadingBottom = false;
242
+ // no more new messages to load
243
+ if (!data.length) {
244
+ this.maxTS = this.newTS;
245
+ this.showNewMessagesCTR = false;
246
+ return [];
247
+ }
248
+ // load new messages and append to the start
249
+ const incoming = [...data].reverse();
250
+ if (this.pages.length === 0)
251
+ this.pages.unshift([]);
252
+ const firstPage = this.pages[0];
253
+ const spaceInFirstPage = this.pageSize - firstPage.length;
254
+ if (spaceInFirstPage > 0) {
255
+ const toFill = incoming.splice(0, spaceInFirstPage);
256
+ firstPage.unshift(...toFill);
258
257
  }
258
+ while (incoming.length > 0) {
259
+ this.pages.unshift(incoming.splice(0, this.pageSize));
260
+ }
261
+ // remove pages if out of bounds
262
+ if (this.pages.length > this.pagesAllowed)
263
+ this.pages.pop();
264
+ // update timestamps
265
+ const lastPage = this.pages[this.pages.length - 1];
266
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
267
+ this.newTS = this.pages[0][0].timeMs;
268
+ this.rerender();
269
+ this.pendingScrollAnchor = scrollAnchor;
270
+ return data;
259
271
  }
260
272
  // Find the element that is closest to the top/bottom of the container
261
273
  getScrollAnchor(edge = 'top') {
@@ -311,11 +323,14 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
311
323
  }
312
324
  }
313
325
  // this method is called recursively based on shouldScrollToBottom (see loadNextPage)
314
- scrollToBottom() {
315
- this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
316
- }
317
- waitForNextFrame() {
318
- return new Promise((resolve) => requestAnimationFrame(() => resolve()));
326
+ async scrollToBottom() {
327
+ this.shouldScrollToBottom = true;
328
+ while (this.shouldScrollToBottom) {
329
+ const response = await this.loadNextPage();
330
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
331
+ if (response.length === 0)
332
+ this.shouldScrollToBottom = false;
333
+ }
319
334
  }
320
335
  rerender() {
321
336
  this.rerenderBoolean = !this.rerenderBoolean;
@@ -324,10 +339,9 @@ const RtkPaginatedList = /*@__PURE__*/ proxyCustomElement(class RtkPaginatedList
324
339
  /**
325
340
  * div.container is flex=column-reversewhich is why div#bottom-scroll comes before div#top-scroll
326
341
  */
327
- 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: () => {
328
- this.shouldScrollToBottom = true;
342
+ return (h(Host, { key: '3e7a77a4254ea0c75513edeaf72a5a77cee0e913' }, h("div", { key: 'f61e72e7a447048fe17ed8321a077841f991bfc5', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '9efd0543b48b5ad5e147a763d258f7ef1a5024c5', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: '4b9bfda38538ceb89f31f317ddcb15d24f75ae8e', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
329
343
  this.scrollToBottom();
330
- } }, 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) }))));
344
+ } }, h("rtk-icon", { key: 'fbcbc895940c8046916a2382806fb403e83a0a53', icon: this.iconPack.chevron_down }))), h("div", { key: 'fe2e51385216cba1905c75db783f037953e4831e', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: '548899e797bbf139526208df3c7696b5859cc884', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: '6353d5970e284369c274c28fc3c774d03fd555cc', 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: 'ff7b4e80f27610c0b73b63ea32fa5331b0cf4630', size: "sm" }), h("div", { key: '8729bf082cde39f7b154fa5816a70b6fb2c7f7df', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
331
345
  }
332
346
  static get style() { return RtkPaginatedListStyle0; }
333
347
  }, [1, "rtk-paginated-list", {
@@ -1,4 +1,4 @@
1
- import { R as RtkChatMessagesUiPaginated$1, d as defineCustomElement$1 } from './p-9213c3fc.js';
1
+ import { R as RtkChatMessagesUiPaginated$1, d as defineCustomElement$1 } from './p-c0db1a83.js';
2
2
 
3
3
  const RtkChatMessagesUiPaginated = RtkChatMessagesUiPaginated$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -11,7 +11,7 @@ import { d as defineCustomElement$8 } from './p-fa476519.js';
11
11
  import { d as defineCustomElement$7 } from './p-2447a26f.js';
12
12
  import { d as defineCustomElement$6 } from './p-819cb785.js';
13
13
  import { d as defineCustomElement$5 } from './p-7148ec6a.js';
14
- import { d as defineCustomElement$4 } from './p-ad8282dc.js';
14
+ import { d as defineCustomElement$4 } from './p-fbc02b1f.js';
15
15
  import { d as defineCustomElement$3 } from './p-4ebf9684.js';
16
16
  import { d as defineCustomElement$2 } from './p-46d99dd9.js';
17
17
 
@@ -1,4 +1,4 @@
1
- import { R as RtkChat$1, d as defineCustomElement$1 } from './p-7e90e964.js';
1
+ import { R as RtkChat$1, d as defineCustomElement$1 } from './p-b64798ac.js';
2
2
 
3
3
  const RtkChat = RtkChat$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -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-7e90e964.js';
11
+ import { d as defineCustomElement$l } from './p-b64798ac.js';
12
12
  import { d as defineCustomElement$k } from './p-28170a8d.js';
13
- import { d as defineCustomElement$j } from './p-9213c3fc.js';
13
+ import { d as defineCustomElement$j } from './p-c0db1a83.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-ad8282dc.js';
26
+ import { d as defineCustomElement$6 } from './p-fbc02b1f.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-ad8282dc.js';
1
+ import { R as RtkPaginatedList$1, d as defineCustomElement$1 } from './p-fbc02b1f.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-20T09:16:34",
2
+ "timestamp": "2026-01-21T08:07:19",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.27.2",
@@ -12671,10 +12671,15 @@ const RtkPaginatedList = class {
12671
12671
  * @param {DataNode} node - The data node to add to the beginning of the list
12672
12672
  */
12673
12673
  async onNewNode(node) {
12674
- // if there are no pages, load the first page
12674
+ // if there are no pages, append to the first page
12675
12675
  if (this.pages.length < 1) {
12676
- this.oldTS = node.timeMs + 1;
12677
- this.loadPrevPage();
12676
+ this.oldTS = node.timeMs;
12677
+ this.pages.unshift([node]);
12678
+ this.newTS = node.timeMs;
12679
+ this.maxTS = node.timeMs;
12680
+ this.rerender();
12681
+ if (this.autoScroll)
12682
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
12678
12683
  }
12679
12684
  else if (this.maxTS === this.newTS) {
12680
12685
  this.maxTS = node.timeMs;
@@ -12686,14 +12691,25 @@ const RtkPaginatedList = class {
12686
12691
  }
12687
12692
  else {
12688
12693
  // if page is at full capacity, load next page
12689
- this.loadNextPage();
12694
+ this.pages.unshift([node]);
12695
+ this.newTS = node.timeMs;
12696
+ // remove pages if out of bounds
12697
+ if (this.pages.length > this.pagesAllowed)
12698
+ this.pages.pop();
12699
+ // update timestamps
12700
+ const lastPage = this.pages[this.pages.length - 1];
12701
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
12702
+ this.newTS = this.pages[0][0].timeMs;
12703
+ this.rerender();
12690
12704
  }
12705
+ if (this.autoScroll)
12706
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
12691
12707
  }
12692
- // If autoscroll is enabled, scroll to the bottom
12693
- if (this.autoScroll) {
12694
- this.shouldScrollToBottom = true;
12695
- this.scrollToBottom();
12708
+ else {
12709
+ if (this.autoScroll)
12710
+ this.scrollToBottom();
12696
12711
  }
12712
+ this.pendingScrollAnchor = null;
12697
12713
  }
12698
12714
  /**
12699
12715
  * Deletes a node anywhere from the list
@@ -12701,7 +12717,6 @@ const RtkPaginatedList = class {
12701
12717
  * */
12702
12718
  async onNodeDelete(id) {
12703
12719
  var _a, _b;
12704
- let didDelete = false;
12705
12720
  for (let i = this.pages.length - 1; i >= 0; i--) {
12706
12721
  const index = this.pages[i].findIndex((node) => node.id === id);
12707
12722
  // if message not found, move on
@@ -12712,17 +12727,17 @@ const RtkPaginatedList = class {
12712
12727
  // if page is empty, delete it
12713
12728
  if (this.pages[i].length === 0)
12714
12729
  this.pages.splice(i, 1);
12715
- didDelete = true;
12730
+ // update timestamps
12731
+ const firstPage = this.pages[0];
12732
+ const lastPage = this.pages[this.pages.length - 1];
12733
+ this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
12734
+ this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
12735
+ // if I have deleted the latest message, update maxTS
12736
+ if (index === 0 && i === 0)
12737
+ this.maxTS = this.newTS;
12738
+ this.rerender();
12716
12739
  break;
12717
12740
  }
12718
- if (!didDelete)
12719
- return;
12720
- // update timestamps
12721
- const firstPage = this.pages[0];
12722
- const lastPage = this.pages[this.pages.length - 1];
12723
- this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
12724
- this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
12725
- this.rerender();
12726
12741
  }
12727
12742
  /**
12728
12743
  * Updates a new node anywhere in the list
@@ -12749,6 +12764,10 @@ const RtkPaginatedList = class {
12749
12764
  this.loadPrevPage();
12750
12765
  if (this.$containerRef) {
12751
12766
  this.$containerRef.onscrollend = async () => {
12767
+ // do not do anything if we are scrolling to bottom
12768
+ if (this.shouldScrollToBottom)
12769
+ return;
12770
+ // handle top and bottom scroll
12752
12771
  if (this.isInView(this.$bottomRef)) {
12753
12772
  await this.loadNextPage();
12754
12773
  }
@@ -12800,54 +12819,47 @@ const RtkPaginatedList = class {
12800
12819
  }
12801
12820
  async loadNextPage() {
12802
12821
  if (this.isLoading)
12803
- return;
12822
+ return [];
12804
12823
  // Do nothing. New timestamp needs to be assigned by loadPrevPage method
12805
12824
  if (!this.newTS) {
12806
12825
  this.showNewMessagesCTR = false;
12807
- this.shouldScrollToBottom = false;
12808
- return;
12826
+ return [];
12809
12827
  }
12810
- // for autoscroll or scroll to bottom button
12811
- const maxAutoLoads = 200;
12812
- let loads = 0;
12813
- let prevNewTS = this.newTS;
12814
12828
  this.isLoading = true;
12815
12829
  this.isLoadingBottom = true;
12816
- while (loads < maxAutoLoads) {
12817
- const scrollAnchor = this.getScrollAnchor('bottom');
12818
- const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
12819
- this.isLoading = false;
12820
- this.isLoadingBottom = false;
12821
- // no more new messages to load
12822
- if (!data.length) {
12823
- this.maxTS = this.newTS;
12824
- this.showNewMessagesCTR = false;
12825
- this.shouldScrollToBottom = false;
12826
- break;
12827
- }
12828
- // load new messages and append to the start
12829
- this.pages.unshift(data.reverse());
12830
- // remove pages if out of bounds
12831
- if (this.pages.length > this.pagesAllowed)
12832
- this.pages.pop();
12833
- // update timestamps
12834
- const lastPage = this.pages[this.pages.length - 1];
12835
- this.oldTS = lastPage[lastPage.length - 1].timeMs;
12836
- this.newTS = this.pages[0][0].timeMs;
12837
- this.rerender();
12838
- this.pendingScrollAnchor = scrollAnchor;
12839
- if (!this.shouldScrollToBottom)
12840
- break;
12841
- // if should scroll to bottom then retrigger
12842
- await this.waitForNextFrame();
12843
- this.scrollToBottom();
12844
- await this.waitForNextFrame();
12845
- // if no new messages, break
12846
- if (this.newTS === prevNewTS)
12847
- break;
12848
- prevNewTS = this.newTS;
12849
- loads++;
12830
+ const scrollAnchor = this.getScrollAnchor('bottom');
12831
+ const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
12832
+ this.isLoading = false;
12833
+ this.isLoadingBottom = false;
12834
+ // no more new messages to load
12835
+ if (!data.length) {
12836
+ this.maxTS = this.newTS;
12837
+ this.showNewMessagesCTR = false;
12838
+ return [];
12850
12839
  }
12840
+ // load new messages and append to the start
12841
+ const incoming = [...data].reverse();
12842
+ if (this.pages.length === 0)
12843
+ this.pages.unshift([]);
12844
+ const firstPage = this.pages[0];
12845
+ const spaceInFirstPage = this.pageSize - firstPage.length;
12846
+ if (spaceInFirstPage > 0) {
12847
+ const toFill = incoming.splice(0, spaceInFirstPage);
12848
+ firstPage.unshift(...toFill);
12849
+ }
12850
+ while (incoming.length > 0) {
12851
+ this.pages.unshift(incoming.splice(0, this.pageSize));
12852
+ }
12853
+ // remove pages if out of bounds
12854
+ if (this.pages.length > this.pagesAllowed)
12855
+ this.pages.pop();
12856
+ // update timestamps
12857
+ const lastPage = this.pages[this.pages.length - 1];
12858
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
12859
+ this.newTS = this.pages[0][0].timeMs;
12860
+ this.rerender();
12861
+ this.pendingScrollAnchor = scrollAnchor;
12862
+ return data;
12851
12863
  }
12852
12864
  // Find the element that is closest to the top/bottom of the container
12853
12865
  getScrollAnchor(edge = 'top') {
@@ -12903,11 +12915,14 @@ const RtkPaginatedList = class {
12903
12915
  }
12904
12916
  }
12905
12917
  // this method is called recursively based on shouldScrollToBottom (see loadNextPage)
12906
- scrollToBottom() {
12907
- this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
12908
- }
12909
- waitForNextFrame() {
12910
- return new Promise((resolve) => requestAnimationFrame(() => resolve()));
12918
+ async scrollToBottom() {
12919
+ this.shouldScrollToBottom = true;
12920
+ while (this.shouldScrollToBottom) {
12921
+ const response = await this.loadNextPage();
12922
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
12923
+ if (response.length === 0)
12924
+ this.shouldScrollToBottom = false;
12925
+ }
12911
12926
  }
12912
12927
  rerender() {
12913
12928
  this.rerenderBoolean = !this.rerenderBoolean;
@@ -12916,10 +12931,9 @@ const RtkPaginatedList = class {
12916
12931
  /**
12917
12932
  * div.container is flex=column-reversewhich is why div#bottom-scroll comes before div#top-scroll
12918
12933
  */
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: () => {
12920
- this.shouldScrollToBottom = true;
12934
+ return (h(Host, { key: '3e7a77a4254ea0c75513edeaf72a5a77cee0e913' }, h("div", { key: 'f61e72e7a447048fe17ed8321a077841f991bfc5', class: "scrollbar container", part: "container", ref: (el) => (this.$containerRef = el) }, h("div", { key: '9efd0543b48b5ad5e147a763d258f7ef1a5024c5', class: { 'show-new-messages-ctr': true, active: this.showNewMessagesCTR } }, h("rtk-button", { key: '4b9bfda38538ceb89f31f317ddcb15d24f75ae8e', class: "show-new-messages", kind: "icon", variant: "secondary", part: "show-new-messages", onClick: () => {
12921
12935
  this.scrollToBottom();
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) }))));
12936
+ } }, h("rtk-icon", { key: 'fbcbc895940c8046916a2382806fb403e83a0a53', icon: this.iconPack.chevron_down }))), h("div", { key: 'fe2e51385216cba1905c75db783f037953e4831e', class: "smallest-dom-element", id: "bottom-scroll", ref: (el) => (this.$bottomRef = el) }), this.isLoadingBottom && this.pages.length > 0 && h("rtk-spinner", { key: '548899e797bbf139526208df3c7696b5859cc884', size: "sm" }), this.isLoading && this.pages.length < 1 && h("rtk-spinner", { key: '6353d5970e284369c274c28fc3c774d03fd555cc', 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: 'ff7b4e80f27610c0b73b63ea32fa5331b0cf4630', size: "sm" }), h("div", { key: '8729bf082cde39f7b154fa5816a70b6fb2c7f7df', class: "smallest-dom-element", id: "top-scroll", ref: (el) => (this.$topRef = el) }))));
12923
12937
  }
12924
12938
  };
12925
12939
  __decorate$2$8([