From 89be27bb9db8850b61d7bd2f7e1cb093642048d5 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 14 Jun 2023 20:28:20 -0400 Subject: [PATCH] Add long polling to update unread counts in navbar. (#1271) * Upping version. * Add long-polling to update unread counts in navbar. - Fixes #1148 * Using async for polling. * Update src/shared/utils.ts Co-authored-by: Sander Saarend * Adding window visibility check, removing generic sleep. --------- Co-authored-by: SleeplessOne1917 Co-authored-by: Sander Saarend --- package.json | 2 +- src/shared/components/app/navbar.tsx | 57 +++++++++++++++------------- src/shared/utils.ts | 16 ++++++++ 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index fd7cf4ad..2298d9e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lemmy-ui", - "version": "0.18.0-beta.6", + "version": "0.18.0-rc.1", "description": "An isomorphic UI for lemmy", "repository": "https://github.com/LemmyNet/lemmy-ui", "license": "AGPL-3.0", diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index bdbac9ff..6d310eef 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -16,8 +16,10 @@ import { isBrowser, myAuth, numToSI, + poll, showAvatars, toast, + updateUnreadCountsInterval, } from "../../utils"; import { Icon } from "../common/icon"; import { PictrsImage } from "../common/pictrs-image"; @@ -64,7 +66,7 @@ export class Navbar extends Component { if (isBrowser()) { // On the first load, check the unreads this.requestNotificationPermission(); - await this.fetchUnreads(); + this.fetchUnreads(); this.requestNotificationPermission(); document.addEventListener("mouseup", this.handleOutsideMenuClick); @@ -406,35 +408,36 @@ export class Navbar extends Component { return amAdmin() || moderatesS; } - async fetchUnreads() { - const auth = myAuth(); - if (auth) { - this.setState({ unreadInboxCountRes: { state: "loading" } }); - this.setState({ - unreadInboxCountRes: await HttpService.client.getUnreadCount({ - auth, - }), - }); - - if (this.moderatesSomething) { - this.setState({ unreadReportCountRes: { state: "loading" } }); - this.setState({ - unreadReportCountRes: await HttpService.client.getReportCount({ - auth, - }), - }); - } - - if (amAdmin()) { - this.setState({ unreadApplicationCountRes: { state: "loading" } }); - this.setState({ - unreadApplicationCountRes: - await HttpService.client.getUnreadRegistrationApplicationCount({ + fetchUnreads() { + poll(async () => { + if (window.document.visibilityState !== "hidden") { + const auth = myAuth(); + if (auth) { + this.setState({ + unreadInboxCountRes: await HttpService.client.getUnreadCount({ auth, }), - }); + }); + + if (this.moderatesSomething) { + this.setState({ + unreadReportCountRes: await HttpService.client.getReportCount({ + auth, + }), + }); + } + + if (amAdmin()) { + this.setState({ + unreadApplicationCountRes: + await HttpService.client.getUnreadRegistrationApplicationCount({ + auth, + }), + }); + } + } } - } + }, updateUnreadCountsInterval); } get unreadInboxCount(): number { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index 46e8601b..2ab0f767 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -75,6 +75,7 @@ export const commentTreeMaxDepth = 8; export const markdownFieldCharacterLimit = 50000; export const maxUploadImages = 20; export const concurrentImageUpload = 4; +export const updateUnreadCountsInterval = 30000; export const relTags = "noopener nofollow"; @@ -1490,3 +1491,18 @@ export function newVote(voteType: VoteType, myVote?: number): number { return myVote == -1 ? 0 : -1; } } + +function sleep(millis: number): Promise { + return new Promise(resolve => setTimeout(resolve, millis)); +} + +/** + * Polls / repeatedly runs a promise, every X milliseconds + */ +export async function poll(promiseFn: any, millis: number) { + if (window.document.visibilityState !== "hidden") { + await promiseFn(); + } + await sleep(millis); + return poll(promiseFn, millis); +}