From 18c48c176e2b7621d559c7093f4eab79e403d342 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 4 Nov 2020 16:08:12 +0800 Subject: feat: Only load cache of dependency of cache. --- FrontEnd/src/app/services/timeline.ts | 41 +++++++++++++++++++++++++++++------ FrontEnd/src/app/services/user.ts | 18 ++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) (limited to 'FrontEnd') diff --git a/FrontEnd/src/app/services/timeline.ts b/FrontEnd/src/app/services/timeline.ts index 9db76281..2cbbffab 100644 --- a/FrontEnd/src/app/services/timeline.ts +++ b/FrontEnd/src/app/services/timeline.ts @@ -1,7 +1,7 @@ import React from "react"; import XRegExp from "xregexp"; import { Observable, from, combineLatest, of } from "rxjs"; -import { map, switchMap, startWith } from "rxjs/operators"; +import { map, switchMap, startWith, filter } from "rxjs/operators"; import { uniqBy } from "lodash"; import { convertError } from "@/utilities/rxjs"; @@ -28,7 +28,13 @@ export type { TimelineVisibility } from "@/http/timeline"; import { dataStorage, throwIfNotNetworkError, BlobOrStatus } from "./common"; import { DataHub, WithSyncStatus } from "./DataHub"; -import { UserAuthInfo, checkLogin, userService, userInfoService } from "./user"; +import { + UserAuthInfo, + checkLogin, + userService, + userInfoService, + User, +} from "./user"; export type TimelineInfo = HttpTimelineInfo; export type TimelineChangePropertyRequest = HttpTimelinePatchRequest; @@ -195,7 +201,11 @@ export class TimelineService { if (timeline != null) { return combineLatest( [timeline.owner, ...timeline.members].map((u) => - userInfoService.getUser$(u) + state.type === "cache" + ? from(userInfoService.getCachedUser(u)).pipe( + filter((u): u is User => u != null) + ) + : userInfoService.getUser$(u) ) ).pipe( map((users) => { @@ -428,12 +438,20 @@ export class TimelineService { return combineLatest([ combineLatest( - state.posts.map((post) => userInfoService.getUser$(post.author)) + state.posts.map((post) => + state.type === "cache" + ? from(userInfoService.getCachedUser(post.author)).pipe( + filter((u): u is User => u != null) + ) + : userInfoService.getUser$(post.author) + ) ), combineLatest( state.posts.map((post) => { if (post.content.type === "image") { - return this.getPostData$(timelineName, post.id); + return state.type === "cache" + ? from(this.getCachedPostData(timelineName, post.id)) + : this.getPostData$(timelineName, post.id); } else { return of(null); } @@ -466,7 +484,7 @@ export class TimelineService { ); } - private getCachedPostData(key: { + private _getCachedPostData(key: { timelineName: string; postId: number; }): Promise { @@ -504,7 +522,7 @@ export class TimelineService { >({ keyToString: (key) => `${key.timelineName}.${key.postId}`, sync: async (key, line) => { - const cache = await this.getCachedPostData(key); + const cache = await this._getCachedPostData(key); if (line.value == null) { if (cache != null) { line.next({ type: "cache", data: cache.data }); @@ -544,6 +562,15 @@ export class TimelineService { }, }); + getCachedPostData( + timelineName: string, + postId: number + ): Promise { + return this._getCachedPostData({ timelineName, postId }).then( + (d) => d?.data ?? null + ); + } + getPostData$(timelineName: string, postId: number): Observable { return this._postDataHub.getObservable({ timelineName, postId }).pipe( map((state): BlobOrStatus => state.data ?? "error"), diff --git a/FrontEnd/src/app/services/user.ts b/FrontEnd/src/app/services/user.ts index f253fc19..cd6d1c15 100644 --- a/FrontEnd/src/app/services/user.ts +++ b/FrontEnd/src/app/services/user.ts @@ -239,7 +239,7 @@ export class UserInfoService { return users.forEach((user) => this.saveUser(user)); } - private getCachedUser(username: string): Promise { + private _getCachedUser(username: string): Promise { return dataStorage.getItem(`user.${username}`); } @@ -247,6 +247,10 @@ export class UserInfoService { return dataStorage.setItem(`user.${user.username}`, user).then(); } + getCachedUser(username: string): Promise { + return this._getCachedUser(username); + } + syncUser(username: string): Promise { return this._userHub.getLineOrCreate(username).sync(); } @@ -258,7 +262,7 @@ export class UserInfoService { >({ sync: async (key, line) => { if (line.value == undefined) { - const cache = await this.getCachedUser(key); + const cache = await this._getCachedUser(key); if (cache != null) { line.next({ user: cache, type: "cache" }); } @@ -272,7 +276,7 @@ export class UserInfoService { if (e instanceof HttpUserNotExistError) { line.next({ type: "notexist" }); } else { - const cache = await this.getCachedUser(key); + const cache = await this._getCachedUser(key); line.next({ user: cache ?? undefined, type: "offline" }); throwIfNotNetworkError(e); } @@ -287,7 +291,7 @@ export class UserInfoService { ); } - private getCachedAvatar(username: string): Promise { + private _getCachedAvatar(username: string): Promise { return dataStorage.getItem(`user.${username}.avatar`); } @@ -297,6 +301,10 @@ export class UserInfoService { .then(); } + getCachedAvatar(username: string): Promise { + return this._getCachedAvatar(username).then((d) => d?.data ?? null); + } + syncAvatar(username: string): Promise { return this._avatarHub.getLineOrCreate(username).sync(); } @@ -307,7 +315,7 @@ export class UserInfoService { | { data?: undefined; type: "notexist" | "offline" } >({ sync: async (key, line) => { - const cache = await this.getCachedAvatar(key); + const cache = await this._getCachedAvatar(key); if (line.value == null) { if (cache != null) { line.next({ data: cache.data, type: "cache" }); -- cgit v1.2.3