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 <sander@saarend.com>

* Adding window visibility check, removing generic sleep.

---------

Co-authored-by: SleeplessOne1917 <abias1122@gmail.com>
Co-authored-by: Sander Saarend <sander@saarend.com>
This commit is contained in:
Dessalines 2023-06-14 20:28:20 -04:00 committed by GitHub
parent d75e0506da
commit 89be27bb9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 28 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "lemmy-ui", "name": "lemmy-ui",
"version": "0.18.0-beta.6", "version": "0.18.0-rc.1",
"description": "An isomorphic UI for lemmy", "description": "An isomorphic UI for lemmy",
"repository": "https://github.com/LemmyNet/lemmy-ui", "repository": "https://github.com/LemmyNet/lemmy-ui",
"license": "AGPL-3.0", "license": "AGPL-3.0",

View file

@ -16,8 +16,10 @@ import {
isBrowser, isBrowser,
myAuth, myAuth,
numToSI, numToSI,
poll,
showAvatars, showAvatars,
toast, toast,
updateUnreadCountsInterval,
} from "../../utils"; } from "../../utils";
import { Icon } from "../common/icon"; import { Icon } from "../common/icon";
import { PictrsImage } from "../common/pictrs-image"; import { PictrsImage } from "../common/pictrs-image";
@ -64,7 +66,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
if (isBrowser()) { if (isBrowser()) {
// On the first load, check the unreads // On the first load, check the unreads
this.requestNotificationPermission(); this.requestNotificationPermission();
await this.fetchUnreads(); this.fetchUnreads();
this.requestNotificationPermission(); this.requestNotificationPermission();
document.addEventListener("mouseup", this.handleOutsideMenuClick); document.addEventListener("mouseup", this.handleOutsideMenuClick);
@ -406,10 +408,11 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
return amAdmin() || moderatesS; return amAdmin() || moderatesS;
} }
async fetchUnreads() { fetchUnreads() {
poll(async () => {
if (window.document.visibilityState !== "hidden") {
const auth = myAuth(); const auth = myAuth();
if (auth) { if (auth) {
this.setState({ unreadInboxCountRes: { state: "loading" } });
this.setState({ this.setState({
unreadInboxCountRes: await HttpService.client.getUnreadCount({ unreadInboxCountRes: await HttpService.client.getUnreadCount({
auth, auth,
@ -417,7 +420,6 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
}); });
if (this.moderatesSomething) { if (this.moderatesSomething) {
this.setState({ unreadReportCountRes: { state: "loading" } });
this.setState({ this.setState({
unreadReportCountRes: await HttpService.client.getReportCount({ unreadReportCountRes: await HttpService.client.getReportCount({
auth, auth,
@ -426,7 +428,6 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
} }
if (amAdmin()) { if (amAdmin()) {
this.setState({ unreadApplicationCountRes: { state: "loading" } });
this.setState({ this.setState({
unreadApplicationCountRes: unreadApplicationCountRes:
await HttpService.client.getUnreadRegistrationApplicationCount({ await HttpService.client.getUnreadRegistrationApplicationCount({
@ -436,6 +437,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
} }
} }
} }
}, updateUnreadCountsInterval);
}
get unreadInboxCount(): number { get unreadInboxCount(): number {
if (this.state.unreadInboxCountRes.state == "success") { if (this.state.unreadInboxCountRes.state == "success") {

View file

@ -75,6 +75,7 @@ export const commentTreeMaxDepth = 8;
export const markdownFieldCharacterLimit = 50000; export const markdownFieldCharacterLimit = 50000;
export const maxUploadImages = 20; export const maxUploadImages = 20;
export const concurrentImageUpload = 4; export const concurrentImageUpload = 4;
export const updateUnreadCountsInterval = 30000;
export const relTags = "noopener nofollow"; export const relTags = "noopener nofollow";
@ -1490,3 +1491,18 @@ export function newVote(voteType: VoteType, myVote?: number): number {
return myVote == -1 ? 0 : -1; return myVote == -1 ? 0 : -1;
} }
} }
function sleep(millis: number): Promise<void> {
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);
}