From 7977ae61f7f32e97dce3ffb682bd530e310b89d7 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 2 Aug 2024 08:55:51 +0100 Subject: [PATCH] FIX: Update do-not-disturb icon in real-time on glimmer header (#28200) To achieve this, a new notifications service is set up with an `isInDoNotDisturb` tracked property. While a user is in do-not-disturb mode, it runs a regular timer until do-not-disturb is over. --- .../javascripts/discourse/app/models/user.js | 10 +++-- .../discourse/app/services/notifications.js | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 app/assets/javascripts/discourse/app/services/notifications.js diff --git a/app/assets/javascripts/discourse/app/models/user.js b/app/assets/javascripts/discourse/app/models/user.js index 000a0e5d8bd..b7264695f8a 100644 --- a/app/assets/javascripts/discourse/app/models/user.js +++ b/app/assets/javascripts/discourse/app/models/user.js @@ -1215,6 +1215,7 @@ export default class User extends RestModel.extend(Evented) { updateDoNotDisturbStatus(ends_at) { this.set("do_not_disturb_until", ends_at); this.appEvents.trigger("do-not-disturb:changed", this.do_not_disturb_until); + getOwner(this).lookup("service:notifications")._checkDoNotDisturb(); } updateDraftProperties(properties) { @@ -1228,10 +1229,11 @@ export default class User extends RestModel.extend(Evented) { } isInDoNotDisturb() { - return ( - this.do_not_disturb_until && - new Date(this.do_not_disturb_until) >= new Date() - ); + if (this !== getOwner(this).lookup("service:current-user")) { + throw "isInDoNotDisturb is only supported for currentUser"; + } + + return getOwner(this).lookup("service:notifications").isInDoNotDisturb; } @discourseComputed( diff --git a/app/assets/javascripts/discourse/app/services/notifications.js b/app/assets/javascripts/discourse/app/services/notifications.js new file mode 100644 index 00000000000..269c7ebbd34 --- /dev/null +++ b/app/assets/javascripts/discourse/app/services/notifications.js @@ -0,0 +1,44 @@ +import { tracked } from "@glimmer/tracking"; +import Service, { service } from "@ember/service"; +import { disableImplicitInjections } from "discourse/lib/implicit-injections"; + +@disableImplicitInjections +export default class NotificationsService extends Service { + @service currentUser; + + @tracked isInDoNotDisturb; + + #dndTimer; + + constructor() { + super(...arguments); + + this._checkDoNotDisturb(); + } + + _checkDoNotDisturb() { + clearTimeout(this.#dndTimer); + + if (this.currentUser?.do_not_disturb_until) { + const remainingMs = this.currentUser.do_not_disturb_until - Date.now(); + + if (remainingMs <= 0) { + this.isInDoNotDisturb = false; + return; + } + + this.isInDoNotDisturb = true; + + this.#dndTimer = setTimeout( + () => this._checkDoNotDisturb(), + Math.min(remainingMs, 60000) + ); + } else { + this.isInDoNotDisturb = false; + } + } + + willDestroy() { + clearTimeout(this.#dndTimer); + } +}