diff options
author | crupest <crupest@outlook.com> | 2021-01-12 21:54:17 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-01-12 21:54:17 +0800 |
commit | b462b3c380258a9a300fce8709530541f2376d92 (patch) | |
tree | ea2b6ee549d262b112f2a583cbb7fd0f1ca1ce38 /FrontEnd/src/app | |
parent | 6d47a07043cb24edf9cf1dc5f535730ac20c9691 (diff) | |
download | timeline-b462b3c380258a9a300fce8709530541f2376d92.tar.gz timeline-b462b3c380258a9a300fce8709530541f2376d92.tar.bz2 timeline-b462b3c380258a9a300fce8709530541f2376d92.zip |
...
Diffstat (limited to 'FrontEnd/src/app')
-rw-r--r-- | FrontEnd/src/app/services/DataHub2.ts | 60 | ||||
-rw-r--r-- | FrontEnd/src/app/services/timeline.ts | 19 | ||||
-rw-r--r-- | FrontEnd/src/app/services/user.ts | 14 |
3 files changed, 51 insertions, 42 deletions
diff --git a/FrontEnd/src/app/services/DataHub2.ts b/FrontEnd/src/app/services/DataHub2.ts index 50ae919b..f0fb724b 100644 --- a/FrontEnd/src/app/services/DataHub2.ts +++ b/FrontEnd/src/app/services/DataHub2.ts @@ -32,6 +32,8 @@ export class DataLine2<TData> { private _current: DataAndStatus<TData> | null = null; private _observers: Subscriber<DataAndStatus<TData>>[] = []; + private _syncPromise: Promise<void> | null = null; + get currentData(): DataAndStatus<TData> | null { return this._current; } @@ -50,7 +52,7 @@ export class DataLine2<TData> { } subscribe(subsriber: Subscriber<DataAndStatus<TData>>): void { - this.sync(); // TODO: Should I sync at this point or let the user sync explicitly. + void this.sync(); // TODO: Should I sync at this point or let the user sync explicitly. this._observers.push(subsriber); const { currentData } = this; if (currentData != null) { @@ -76,36 +78,44 @@ export class DataLine2<TData> { }); } - sync(): void { - const { currentData } = this; - if (currentData != null && currentData.status === "syncing") return; - this.next({ data: currentData?.data ?? null, status: "syncing" }); - void this.config.getSavedData().then((savedData) => { - if (currentData == null && savedData != null) { - this.next({ data: savedData, status: "syncing" }); - } - return this.config.fetchData(savedData).then((data) => { - if (data == null) { - this.next({ - data: savedData, - status: "offline", - }); - } else { - return this.config.saveData(data).then(() => { - this.next({ data: data, status: "synced" }); - }); - } - }); + private syncWithAction(action: () => Promise<void>): Promise<void> { + if (this._syncPromise != null) return this._syncPromise; + this._syncPromise = action().then(() => { + this._syncPromise = null; }); + return this._syncPromise; + } + + sync(): Promise<void> { + return this.syncWithAction(this.doSync.bind(this)); } - save(data: TData): void { + private async doSync(): Promise<void> { const { currentData } = this; - if (currentData != null && currentData.status === "syncing") return; this.next({ data: currentData?.data ?? null, status: "syncing" }); - void this.config.saveData(data).then(() => { + const savedData = await this.config.getSavedData(); + if (currentData == null && savedData != null) { + this.next({ data: savedData, status: "syncing" }); + } + const data = await this.config.fetchData(savedData); + if (data == null) { + this.next({ + data: savedData, + status: "offline", + }); + } else { + await this.config.saveData(data); this.next({ data: data, status: "synced" }); - }); + } + } + + save(data: TData): Promise<void> { + return this.syncWithAction(this.doSave.bind(this, data)); + } + + private async doSave(data: TData): Promise<void> { + await this.config.saveData(data); + this.next({ data: data, status: "synced" }); } getSavedData(): Promise<TData | null> { diff --git a/FrontEnd/src/app/services/timeline.ts b/FrontEnd/src/app/services/timeline.ts index 8bc1d40b..7d239fbf 100644 --- a/FrontEnd/src/app/services/timeline.ts +++ b/FrontEnd/src/app/services/timeline.ts @@ -104,8 +104,9 @@ export class TimelineService { saveData: async (timelineName, data) => { if (data === "notexist") return; - userInfoService.saveUser(data.owner); - userInfoService.saveUsers(data.members); + // TODO: Avoid save same user. + void userInfoService.saveUser(data.owner); + void userInfoService.saveUsers(data.members); await dataStorage.setItem<TimelineData>( this.generateTimelineDataStorageKey(timelineName), @@ -157,8 +158,8 @@ export class TimelineService { }, }); - syncTimeline(timelineName: string): void { - this.timelineHub.getLine(timelineName).sync(); + syncTimeline(timelineName: string): Promise<void> { + return this.timelineHub.getLine(timelineName).sync(); } createTimeline(timelineName: string): Observable<TimelineInfo> { @@ -222,7 +223,7 @@ export class TimelineService { }; data.posts.forEach((p) => { - userInfoService.saveUser(p.author); + void userInfoService.saveUser(p.author); }); await dataStorage.setItem<TimelinePostsData>( @@ -342,8 +343,8 @@ export class TimelineService { }, }); - syncPosts(timelineName: string): void { - this.postsHub.getLine(timelineName).sync(); + syncPosts(timelineName: string): Promise<void> { + return this.postsHub.getLine(timelineName).sync(); } createPost( @@ -354,7 +355,7 @@ export class TimelineService { getHttpTimelineClient() .postPost(timelineName, request) .then(() => { - this.syncPosts(timelineName); + void this.syncPosts(timelineName); }) ); } @@ -364,7 +365,7 @@ export class TimelineService { getHttpTimelineClient() .deletePost(timelineName, postId) .then(() => { - this.syncPosts(timelineName); + void this.syncPosts(timelineName); }) ); } diff --git a/FrontEnd/src/app/services/user.ts b/FrontEnd/src/app/services/user.ts index 5c4e3ae0..611a86ae 100644 --- a/FrontEnd/src/app/services/user.ts +++ b/FrontEnd/src/app/services/user.ts @@ -248,12 +248,12 @@ export function checkLogin(): AuthUser { export class UserNotExistError extends Error {} export class UserInfoService { - saveUser(user: HttpUser): void { - this.userHub.getLine(user.username).save(user); + saveUser(user: HttpUser): Promise<void> { + return this.userHub.getLine(user.username).save(user); } - saveUsers(users: HttpUser[]): void { - return users.forEach((user) => this.saveUser(user)); + saveUsers(users: HttpUser[]): Promise<void> { + return Promise.all(users.map((user) => this.saveUser(user))).then(); } async getCachedUser(username: string): Promise<HttpUser | null> { @@ -351,15 +351,13 @@ export class UserInfoService { async setAvatar(username: string, blob: Blob): Promise<void> { const etag = await getHttpUserClient().putAvatar(username, blob); - this.avatarHub.getLine(username).save({ data: blob, etag }); + await this.avatarHub.getLine(username).save({ data: blob, etag }); } async setNickname(username: string, nickname: string): Promise<void> { return getHttpUserClient() .patch(username, { nickname }) - .then((user) => { - this.saveUser(user); - }); + .then((user) => this.saveUser(user)); } } |