]> Untitled Git - lemmy-ui.git/commitdiff
Cache post listings and restore listing state when using browser back navigation...
authordudeami0 <dudeami0@gmail.com>
Fri, 23 Jun 2023 18:27:35 +0000 (14:27 -0400)
committerJay Sitter <jay@jaysitter.com>
Sat, 24 Jun 2023 04:14:10 +0000 (00:14 -0400)
src/shared/components/home/home.tsx
src/shared/services/HomeCacheService.ts [new file with mode: 0644]
src/shared/services/index.ts

index 71e5842e63775abacf6c0fc88e9028527fe7a0a3..7fa942af34c24e2633349229b3f7a900ac9fedc2 100644 (file)
@@ -78,7 +78,12 @@ import {
   InitialFetchRequest,
 } from "../../interfaces";
 import { mdToHtml } from "../../markdown";
-import { FirstLoadService, I18NextService, UserService } from "../../services";
+import {
+  FirstLoadService,
+  HomeCacheService,
+  I18NextService,
+  UserService,
+} from "../../services";
 import { HttpService, RequestState } from "../../services/HttpService";
 import { setupTippy } from "../../tippy";
 import { toast } from "../../toast";
@@ -278,9 +283,15 @@ export class Home extends Component<any, HomeState> {
           ?.content,
         isIsomorphic: true,
       };
+
+      HomeCacheService.postsRes = postsRes;
     }
   }
 
+  componentWillUnmount() {
+    HomeCacheService.activate();
+  }
+
   async componentDidMount() {
     if (
       !this.state.isIsomorphic ||
@@ -650,6 +661,8 @@ export class Home extends Component<any, HomeState> {
 
     if (dataType === DataType.Post) {
       switch (this.state.postsRes?.state) {
+        case "empty":
+          return <div style="min-height: 20000px;"></div>;
         case "loading":
           return (
             <h5>
@@ -777,17 +790,30 @@ export class Home extends Component<any, HomeState> {
     const { dataType, page, listingType, sort } = getHomeQueryParams();
 
     if (dataType === DataType.Post) {
-      this.setState({ postsRes: { state: "loading" } });
-      this.setState({
-        postsRes: await HttpService.client.getPosts({
-          page,
-          limit: fetchLimit,
-          sort,
-          saved_only: false,
-          type_: listingType,
-          auth,
-        }),
-      });
+      if (HomeCacheService.active) {
+        const { postsRes, scrollY } = HomeCacheService;
+        HomeCacheService.deactivate();
+        this.setState({ postsRes });
+        window.scrollTo({
+          left: 0,
+          top: scrollY,
+          behavior: "instant",
+        });
+      } else {
+        this.setState({ postsRes: { state: "loading" } });
+        this.setState({
+          postsRes: await HttpService.client.getPosts({
+            page,
+            limit: fetchLimit,
+            sort,
+            saved_only: false,
+            type_: listingType,
+            auth,
+          }),
+        });
+
+        HomeCacheService.postsRes = this.state.postsRes;
+      }
     } else {
       this.setState({ commentsRes: { state: "loading" } });
       this.setState({
diff --git a/src/shared/services/HomeCacheService.ts b/src/shared/services/HomeCacheService.ts
new file mode 100644 (file)
index 0000000..9f33dc4
--- /dev/null
@@ -0,0 +1,60 @@
+import { GetPostsResponse } from "lemmy-js-client";
+import { RequestState } from "./HttpService.js";
+
+/**
+ * Service to cache home post listings and restore home state when user uses the browser back buttons.
+ */
+export class HomeCacheService {
+  static #_instance: HomeCacheService;
+  historyIdx = 0;
+  scrollY = 0;
+  posts: RequestState<GetPostsResponse> = { state: "empty" };
+
+  get active() {
+    return (
+      this.historyIdx === window.history.state.idx + 1 &&
+      this.posts.state === "success"
+    );
+  }
+
+  deactivate() {
+    this.historyIdx = 0;
+  }
+
+  activate() {
+    this.scrollY = window.scrollY;
+    this.historyIdx = window.history.state.idx;
+  }
+
+  static get #Instance() {
+    return this.#_instance ?? (this.#_instance = new this());
+  }
+
+  public static get scrollY() {
+    return this.#Instance.scrollY;
+  }
+
+  public static get historyIdx() {
+    return this.#Instance.historyIdx;
+  }
+
+  public static set postsRes(posts: RequestState<GetPostsResponse>) {
+    this.#Instance.posts = posts;
+  }
+
+  public static get postsRes() {
+    return this.#Instance.posts;
+  }
+
+  public static get active() {
+    return this.#Instance.active;
+  }
+
+  public static deactivate() {
+    this.#Instance.deactivate();
+  }
+
+  public static activate() {
+    this.#Instance.activate();
+  }
+}
index 5856245ac08a02475956c97d287a72be6abded88..620293c4a4c54f3e2459771080dd0fe5f2bdea0b 100644 (file)
@@ -1,5 +1,6 @@
 export { FirstLoadService } from "./FirstLoadService";
 export { HistoryService } from "./HistoryService";
+export { HomeCacheService } from "./HomeCacheService";
 export { HttpService } from "./HttpService";
 export { I18NextService } from "./I18NextService";
 export { UserService } from "./UserService";