Advertisement
Guest User

Lemmy Sort and Scroll

a guest
Jul 16th, 2023
705
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name             Lemmy Sort and Scroll
  3. // @description      Implements infinite scrolling and changes default sorting behavior.
  4. // @version          0.3
  5. // @author           [email protected]
  6. // @run-at           document-start
  7. // @grant            none
  8. // @match            https://sh.itjust.works/*
  9. // @match            https://burggit.moe/*
  10. // @match            https://lemmy.world/*
  11. // @match            https://lemm.ee/*
  12. // @match            https://lemmy.ml/*
  13. // @match            https://lemmynsfw.com/*
  14. // ==/UserScript==
  15.  
  16. // Don't forget to add your home instance to the match list above.
  17.  
  18. const defaultSort = 'Top';
  19.  
  20. function addScript(text) {
  21.   text = text.replaceAll(`commentSort:"Hot"`, `commentSort:"${defaultSort}"`);
  22.   text = text.replaceAll(
  23.     'this.state.postsRes.data.posts',
  24.     `(window.LEAKED_HOME=this,this.state.postsRes.data.posts)`
  25.   );
  26.   var newScript = document.createElement('script');
  27.   newScript.type = 'text/javascript';
  28.   newScript.textContent = text;
  29.   var head = document.getElementsByTagName('head')[0];
  30.   head.appendChild(newScript);
  31. }
  32.  
  33. window.addEventListener('beforescriptexecute', async function (e) {
  34.   const src = e.target.src;
  35.   if (src.endsWith('client.js')) {
  36.     e.preventDefault();
  37.     e.stopPropagation();
  38.     const response = await fetch(src);
  39.     addScript(await response.text());
  40.   }
  41. });
  42.  
  43. let currentPage = 1;
  44. let ongoingRequest = false;
  45.  
  46. let lastUrl = location.href;
  47. const observer = new MutationObserver(() => {
  48.   if (location.href !== lastUrl) {
  49.     lastUrl = location.href;
  50.     currentPage = Number(new URLSearchParams(location.search).get('page') ?? 1);
  51.     ongoingRequest = false;
  52.   }
  53.  
  54.   if (document.querySelector('.post-listings') && document.querySelector('.paginator button')) {
  55.     if (document.querySelectorAll('.post-listing').length < 20) {
  56.       showEndMessage();
  57.     } else {
  58.       clearPaginator();
  59.     }
  60.   }
  61. });
  62.  
  63. observer.observe(document.documentElement, { childList: true, subtree: true });
  64.  
  65. window.addEventListener('scroll', async function (e) {
  66.   const referenceBox = document.querySelector('.post-listings')?.getBoundingClientRect();
  67.  
  68.   if (scrollY == 0 || ongoingRequest || !referenceBox || !LEAKED_HOME) return;
  69.  
  70.   if (LEAKED_HOME.state.postsRes.data.posts.length < 20) {
  71.     showEndMessage();
  72.     return;
  73.   }
  74.  
  75.   if (innerHeight + 300 > referenceBox.bottom) {
  76.     ongoingRequest = true;
  77.     currentPage += 1;
  78.  
  79.     const authToken = document.cookie.split('=')[1];
  80.     const communityName = location.pathname.split('/')[2] ?? '';
  81.  
  82.     let { sort, listing } = getSortAndListing();
  83.  
  84.     let query = new URLSearchParams({
  85.       page: currentPage,
  86.       limit: 20,
  87.       sort: sort,
  88.       type_: listing,
  89.       auth: authToken,
  90.     });
  91.  
  92.     if (communityName) {
  93.       query.set('community_name', communityName);
  94.     }
  95.  
  96.     try {
  97.       const curHome = LEAKED_HOME;
  98.  
  99.       showSpinner();
  100.  
  101.       const response = await fetch(`${location.origin}/api/v3/post/list?${query.toString()}`);
  102.       const posts = (await response.json()).posts;
  103.  
  104.       if (LEAKED_HOME != curHome) {
  105.         return;
  106.       }
  107.  
  108.       clearPaginator();
  109.  
  110.       LEAKED_HOME.state.postsRes.data.posts.push(...posts);
  111.       LEAKED_HOME.forceUpdate();
  112.  
  113.       if (posts.length == 20) {
  114.         ongoingRequest = false;
  115.       } else {
  116.         showEndMessage();
  117.       }
  118.     } catch {
  119.       ongoingRequest = false;
  120.     }
  121.   }
  122. });
  123.  
  124. function getSortAndListing() {
  125.   const queryParams = new URLSearchParams(location.search);
  126.   const defaultSort =
  127.     isoData?.site_res?.my_user?.local_user_view?.local_user?.default_sort_type ?? 'Active';
  128.   const defaultListing =
  129.     isoData?.site_res?.my_user?.local_user_view?.local_user?.default_listing_type ?? 'Local';
  130.  
  131.   return {
  132.     sort: queryParams.get('sort') ?? defaultSort,
  133.     listing: queryParams.get('listingType') ?? defaultListing,
  134.   };
  135. }
  136.  
  137. function showEndMessage() {
  138.   let paginator = document.querySelector('.paginator');
  139.   if (document.querySelector('.post-listing')) {
  140.     paginator.innerHTML = 'There are no more posts!';
  141.   } else {
  142.     clearPaginator();
  143.   }
  144. }
  145.  
  146. function showSpinner() {
  147.   let paginator = document.querySelector('.paginator');
  148.   paginator.innerHTML =
  149.     '<svg class="icon spin spinner-large" viewBox="0 0 32 32"><path xmlns="http://www.w3.org/2000/svg" d="M16 32c-4.274 0-8.292-1.664-11.314-4.686s-4.686-7.040-4.686-11.314c0-3.026 0.849-5.973 2.456-8.522 1.563-2.478 3.771-4.48 6.386-5.791l1.344 2.682c-2.126 1.065-3.922 2.693-5.192 4.708-1.305 2.069-1.994 4.462-1.994 6.922 0 7.168 5.832 13 13 13s13-5.832 13-13c0-2.459-0.69-4.853-1.994-6.922-1.271-2.015-3.066-3.643-5.192-4.708l1.344-2.682c2.615 1.31 4.824 3.313 6.386 5.791 1.607 2.549 2.456 5.495 2.456 8.522 0 4.274-1.664 8.292-4.686 11.314s-7.040 4.686-11.314 4.686z"/></svg>';
  150. }
  151.  
  152. function clearPaginator() {
  153.   let paginator = document.querySelector('.paginator');
  154.   paginator.innerHTML = '';
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement