@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.
@@ -2135,10 +2135,15 @@ const RtkPaginatedList = class {
2135
2135
  * @param {DataNode} node - The data node to add to the beginning of the list
2136
2136
  */
2137
2137
  async onNewNode(node) {
2138
- // if there are no pages, load the first page
2138
+ // if there are no pages, append to the first page
2139
2139
  if (this.pages.length < 1) {
2140
- this.oldTS = node.timeMs + 1;
2141
- this.loadPrevPage();
2140
+ this.oldTS = node.timeMs;
2141
+ this.pages.unshift([node]);
2142
+ this.newTS = node.timeMs;
2143
+ this.maxTS = node.timeMs;
2144
+ this.rerender();
2145
+ if (this.autoScroll)
2146
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
2142
2147
  }
2143
2148
  else if (this.maxTS === this.newTS) {
2144
2149
  this.maxTS = node.timeMs;
@@ -2150,14 +2155,25 @@ const RtkPaginatedList = class {
2150
2155
  }
2151
2156
  else {
2152
2157
  // if page is at full capacity, load next page
2153
- this.loadNextPage();
2158
+ this.pages.unshift([node]);
2159
+ this.newTS = node.timeMs;
2160
+ // remove pages if out of bounds
2161
+ if (this.pages.length > this.pagesAllowed)
2162
+ this.pages.pop();
2163
+ // update timestamps
2164
+ const lastPage = this.pages[this.pages.length - 1];
2165
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
2166
+ this.newTS = this.pages[0][0].timeMs;
2167
+ this.rerender();
2154
2168
  }
2169
+ if (this.autoScroll)
2170
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
2155
2171
  }
2156
- // If autoscroll is enabled, scroll to the bottom
2157
- if (this.autoScroll) {
2158
- this.shouldScrollToBottom = true;
2159
- this.scrollToBottom();
2172
+ else {
2173
+ if (this.autoScroll)
2174
+ this.scrollToBottom();
2160
2175
  }
2176
+ this.pendingScrollAnchor = null;
2161
2177
  }
2162
2178
  /**
2163
2179
  * Deletes a node anywhere from the list
@@ -2165,7 +2181,6 @@ const RtkPaginatedList = class {
2165
2181
  * */
2166
2182
  async onNodeDelete(id) {
2167
2183
  var _a, _b;
2168
- let didDelete = false;
2169
2184
  for (let i = this.pages.length - 1; i >= 0; i--) {
2170
2185
  const index = this.pages[i].findIndex((node) => node.id === id);
2171
2186
  // if message not found, move on
@@ -2176,17 +2191,17 @@ const RtkPaginatedList = class {
2176
2191
  // if page is empty, delete it
2177
2192
  if (this.pages[i].length === 0)
2178
2193
  this.pages.splice(i, 1);
2179
- didDelete = true;
2194
+ // update timestamps
2195
+ const firstPage = this.pages[0];
2196
+ const lastPage = this.pages[this.pages.length - 1];
2197
+ this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
2198
+ this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
2199
+ // if I have deleted the latest message, update maxTS
2200
+ if (index === 0 && i === 0)
2201
+ this.maxTS = this.newTS;
2202
+ this.rerender();
2180
2203
  break;
2181
2204
  }
2182
- if (!didDelete)
2183
- return;
2184
- // update timestamps
2185
- const firstPage = this.pages[0];
2186
- const lastPage = this.pages[this.pages.length - 1];
2187
- this.newTS = (_a = firstPage === null || firstPage === void 0 ? void 0 : firstPage[0]) === null || _a === void 0 ? void 0 : _a.timeMs;
2188
- this.oldTS = (_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage[lastPage.length - 1]) === null || _b === void 0 ? void 0 : _b.timeMs;
2189
- this.rerender();
2190
2205
  }
2191
2206
  /**
2192
2207
  * Updates a new node anywhere in the list
@@ -2213,6 +2228,10 @@ const RtkPaginatedList = class {
2213
2228
  this.loadPrevPage();
2214
2229
  if (this.$containerRef) {
2215
2230
  this.$containerRef.onscrollend = async () => {
2231
+ // do not do anything if we are scrolling to bottom
2232
+ if (this.shouldScrollToBottom)
2233
+ return;
2234
+ // handle top and bottom scroll
2216
2235
  if (this.isInView(this.$bottomRef)) {
2217
2236
  await this.loadNextPage();
2218
2237
  }
@@ -2264,54 +2283,47 @@ const RtkPaginatedList = class {
2264
2283
  }
2265
2284
  async loadNextPage() {
2266
2285
  if (this.isLoading)
2267
- return;
2286
+ return [];
2268
2287
  // Do nothing. New timestamp needs to be assigned by loadPrevPage method
2269
2288
  if (!this.newTS) {
2270
2289
  this.showNewMessagesCTR = false;
2271
- this.shouldScrollToBottom = false;
2272
- return;
2290
+ return [];
2273
2291
  }
2274
- // for autoscroll or scroll to bottom button
2275
- const maxAutoLoads = 200;
2276
- let loads = 0;
2277
- let prevNewTS = this.newTS;
2278
2292
  this.isLoading = true;
2279
2293
  this.isLoadingBottom = true;
2280
- while (loads < maxAutoLoads) {
2281
- const scrollAnchor = this.getScrollAnchor('bottom');
2282
- const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
2283
- this.isLoading = false;
2284
- this.isLoadingBottom = false;
2285
- // no more new messages to load
2286
- if (!data.length) {
2287
- this.maxTS = this.newTS;
2288
- this.showNewMessagesCTR = false;
2289
- this.shouldScrollToBottom = false;
2290
- break;
2291
- }
2292
- // load new messages and append to the start
2293
- this.pages.unshift(data.reverse());
2294
- // remove pages if out of bounds
2295
- if (this.pages.length > this.pagesAllowed)
2296
- this.pages.pop();
2297
- // update timestamps
2298
- const lastPage = this.pages[this.pages.length - 1];
2299
- this.oldTS = lastPage[lastPage.length - 1].timeMs;
2300
- this.newTS = this.pages[0][0].timeMs;
2301
- this.rerender();
2302
- this.pendingScrollAnchor = scrollAnchor;
2303
- if (!this.shouldScrollToBottom)
2304
- break;
2305
- // if should scroll to bottom then retrigger
2306
- await this.waitForNextFrame();
2307
- this.scrollToBottom();
2308
- await this.waitForNextFrame();
2309
- // if no new messages, break
2310
- if (this.newTS === prevNewTS)
2311
- break;
2312
- prevNewTS = this.newTS;
2313
- loads++;
2294
+ const scrollAnchor = this.getScrollAnchor('bottom');
2295
+ const data = await this.fetchData(this.newTS + 1, this.pageSize, false);
2296
+ this.isLoading = false;
2297
+ this.isLoadingBottom = false;
2298
+ // no more new messages to load
2299
+ if (!data.length) {
2300
+ this.maxTS = this.newTS;
2301
+ this.showNewMessagesCTR = false;
2302
+ return [];
2303
+ }
2304
+ // load new messages and append to the start
2305
+ const incoming = [...data].reverse();
2306
+ if (this.pages.length === 0)
2307
+ this.pages.unshift([]);
2308
+ const firstPage = this.pages[0];
2309
+ const spaceInFirstPage = this.pageSize - firstPage.length;
2310
+ if (spaceInFirstPage > 0) {
2311
+ const toFill = incoming.splice(0, spaceInFirstPage);
2312
+ firstPage.unshift(...toFill);
2314
2313
  }
2314
+ while (incoming.length > 0) {
2315
+ this.pages.unshift(incoming.splice(0, this.pageSize));
2316
+ }
2317
+ // remove pages if out of bounds
2318
+ if (this.pages.length > this.pagesAllowed)
2319
+ this.pages.pop();
2320
+ // update timestamps
2321
+ const lastPage = this.pages[this.pages.length - 1];
2322
+ this.oldTS = lastPage[lastPage.length - 1].timeMs;
2323
+ this.newTS = this.pages[0][0].timeMs;
2324
+ this.rerender();
2325
+ this.pendingScrollAnchor = scrollAnchor;
2326
+ return data;
2315
2327
  }
2316
2328
  // Find the element that is closest to the top/bottom of the container
2317
2329
  getScrollAnchor(edge = 'top') {
@@ -2367,11 +2379,14 @@ const RtkPaginatedList = class {
2367
2379
  }
2368
2380
  }
2369
2381
  // this method is called recursively based on shouldScrollToBottom (see loadNextPage)
2370
- scrollToBottom() {
2371
- this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
2372
- }
2373
- waitForNextFrame() {
2374
- return new Promise((resolve) => requestAnimationFrame(() => resolve()));
2382
+ async scrollToBottom() {
2383
+ this.shouldScrollToBottom = true;
2384
+ while (this.shouldScrollToBottom) {
2385
+ const response = await this.loadNextPage();
2386
+ this.$bottomRef.scrollIntoView({ behavior: 'smooth' });
2387
+ if (response.length === 0)
2388
+ this.shouldScrollToBottom = false;
2389
+ }
2375
2390
  }
2376
2391
  rerender() {
2377
2392
  this.rerenderBoolean = !this.rerenderBoolean;
@@ -2380,10 +2395,9 @@ const RtkPaginatedList = class {
2380
2395
  /**
2381
2396
  * div.container is flex=column-reversewhich is why div#bottom-scroll comes before div#top-scroll
2382
2397
  */
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: () => {
2384
- this.shouldScrollToBottom = true;
2398
+ 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: () => {
2385
2399
  this.scrollToBottom();
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) }))));
2400
+ } }, 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) }))));
2387
2401
  }
2388
2402
  };
2389
2403
  __decorate$2([