blob: 4dde91c77adac27f8dd23a61ba13542e8f0f07f0 [file] [log] [blame]
Adrià Vilanova Martínezb523be92024-05-25 19:14:19 +02001import {getOptions, isOptionEnabled} from '../../../common/options/optionsUtils.js';
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +01002
3const kInteropLoadMoreClasses = {
Adrià Vilanova Martínez88854972022-08-28 11:57:12 +02004 // New (interop) UI without nested replies
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +01005 'scTailwindThreadMorebuttonload-all': 'threadall',
6 'scTailwindThreadMorebuttonload-more': 'thread',
Adrià Vilanova Martínez88854972022-08-28 11:57:12 +02007
8 // New (interop) UI with nested replies
9 'scTailwindThreadMessagegapload-all': 'threadall',
10 'scTailwindThreadMessagegapload-more': 'thread',
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010011};
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020012const kArtificialScrollingDelay = 3500;
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010013
Adrià Vilanova Martínez18d03c42024-04-21 16:43:01 +020014export default class CCInfiniteScroll {
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010015 constructor() {
16 this.intersectionObserver = null;
17 }
18
19 setUpIntersectionObserver(node, isScrollableContent) {
20 if (this.intersectionObserver === null) {
21 var scrollableContent = isScrollableContent ?
22 node :
23 node.querySelector('.scrollable-content');
24 if (scrollableContent !== null) {
25 let intersectionOptions = {
26 root: scrollableContent,
27 rootMargin: '0px',
28 threshold: 1.0,
29 };
30 this.intersectionObserver = new IntersectionObserver(
31 this.intersectionCallback, intersectionOptions);
32 }
33 }
34 }
35
36 intersectionCallback(entries, observer) {
37 entries.forEach(entry => {
38 if (entry.isIntersecting) {
39 console.debug('[infinitescroll] Clicking button: ', entry.target);
40 entry.target.click();
41 }
42 });
43 }
44
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020045 isPotentiallyArtificialScroll() {
46 return window.location.href.includes('/message/');
47 }
48
49 observeWithPotentialDelay(node) {
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010050 if (this.intersectionObserver === null) {
51 console.warn(
52 '[infinitescroll] ' +
53 'The intersectionObserver is not ready yet.');
54 return;
55 }
56
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020057 if (this.isPotentiallyArtificialScroll()) {
58 window.setTimeout(
59 () => {this.intersectionObserver.observe(node)},
60 kArtificialScrollingDelay);
61 } else {
62 this.intersectionObserver.observe(node);
63 }
64 }
65
66 observeLoadMoreBar(bar) {
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010067 getOptions(['thread', 'threadall']).then(threadOptions => {
68 if (threadOptions.thread)
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020069 this.observeWithPotentialDelay(bar.querySelector('.load-more-button'));
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010070 if (threadOptions.threadall)
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020071 this.observeWithPotentialDelay(bar.querySelector('.load-all-button'));
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010072 });
73 }
74
75 observeLoadMoreInteropBtn(btn) {
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010076 let parentClasses = btn.parentNode?.classList;
77 let feature = null;
78 for (const [c, f] of Object.entries(kInteropLoadMoreClasses)) {
79 if (parentClasses?.contains?.(c)) {
80 feature = f;
81 break;
82 }
83 }
84 if (feature === null) return;
85 isOptionEnabled(feature).then(isEnabled => {
Adrià Vilanova Martínezc8007802022-10-01 19:42:19 +020086 if (isEnabled) this.observeWithPotentialDelay(btn);
Adrià Vilanova Martíneza7ae3db2022-01-28 11:57:27 +010087 });
88 }
89};