FIX: attempts to reconciliate tracking state (#21416)

After a long time with no activity or hidden browser (2.5 minutes), the app will re-sync the chat user-tracking-state to ensure unreads are synced.

We might also need to couple this later with more recovering logic.
This commit is contained in:
Joffrey JAFFEUX 2023-05-08 09:09:35 +02:00 committed by GitHub
parent 963bb3406e
commit e8d6277062
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 17 deletions

View File

@ -223,11 +223,15 @@ export default class ChatChannel extends RestModel {
updateMembership(membership) {
this.currentUserMembership.following = membership.following;
this.currentUserMembership.muted = membership.muted;
this.currentUserMembership.last_read_message_id =
membership.last_read_message_id;
this.currentUserMembership.desktop_notification_level =
membership.desktop_notification_level;
this.currentUserMembership.mobile_notification_level =
membership.mobile_notification_level;
this.currentUserMembership.unread_count = membership.unread_count;
this.currentUserMembership.unread_mentions = membership.unread_mentions;
this.currentUserMembership.muted = membership.muted;
}
updateLastReadMessage(messageId) {

View File

@ -218,11 +218,7 @@ export default class ChatApi extends Service {
* @returns {Promise}
*/
listCurrentUserChannels() {
return this.#getRequest("/channels/me").then((result) => {
return (result?.channels || []).map((channel) =>
this.chatChannelsManager.store(channel)
);
});
return this.#getRequest("/channels/me");
}
/**

View File

@ -51,6 +51,11 @@ export default class ChatSubscriptionsManager extends Service {
this._channelSubscriptions.delete(channel.id);
}
restartChannelsSubscriptions(messageBusIds) {
this.stopChannelsSubscriptions();
this.startChannelsSubscriptions(messageBusIds);
}
startChannelsSubscriptions(messageBusIds) {
this._startNewChannelSubscription(messageBusIds.new_channel);
this._startChannelArchiveStatusSubscription(messageBusIds.archive_status);
@ -251,17 +256,11 @@ export default class ChatSubscriptionsManager extends Service {
@bind
_updateChannelTrackingData(channelId, trackingData) {
this.chatChannelsManager.find(channelId).then((channel) => {
if (
!channel?.currentUserMembership?.last_read_message_id ||
parseInt(channel?.currentUserMembership?.last_read_message_id, 10) <=
trackingData.last_read_message_id
) {
channel.currentUserMembership.last_read_message_id =
trackingData.last_read_message_id;
channel.currentUserMembership.unread_count = trackingData.unread_count;
channel.currentUserMembership.unread_mentions =
trackingData.mention_count;
}
channel.currentUserMembership.last_read_message_id =
trackingData.last_read_message_id;
channel.currentUserMembership.unread_count = trackingData.unread_count;
channel.currentUserMembership.unread_mentions =
trackingData.mention_count;
});
}

View File

@ -9,6 +9,11 @@ import { and } from "@ember/object/computed";
import { computed } from "@ember/object";
import discourseLater from "discourse-common/lib/later";
import ChatMessage from "discourse/plugins/chat/discourse/models/chat-message";
import {
onPresenceChange,
removeOnPresenceChange,
} from "discourse/lib/user-presence";
import { bind } from "discourse-common/utils/decorators";
const CHAT_ONLINE_OPTIONS = {
userUnseenTime: 300000, // 5 minutes seconds with no interaction
@ -16,6 +21,7 @@ const CHAT_ONLINE_OPTIONS = {
};
export default class Chat extends Service {
@service chatApi;
@service appEvents;
@service currentUser;
@service chatNotificationManager;
@ -89,6 +95,36 @@ export default class Chat extends Service {
if (this.userCanChat) {
this.presenceChannel = this.presence.getChannel("/chat/online");
onPresenceChange({
callback: this.onPresenceChangeCallback,
browserHiddenTime: 150000,
userUnseenTime: 150000,
});
}
}
@bind
onPresenceChangeCallback(present) {
if (present) {
this.chatApi.listCurrentUserChannels().then((channels) => {
this.chatSubscriptionsManager.restartChannelsSubscriptions(
channels.meta.message_bus_last_ids
);
[
...channels.public_channels,
...channels.direct_message_channels,
].forEach((channelObject) => {
this.chatChannelsManager
.find(channelObject.id, { fetchIfNotFound: false })
.then((channel) => {
if (channel) {
channel.updateMembership(channelObject.current_user_membership);
}
});
});
});
}
}
@ -148,6 +184,7 @@ export default class Chat extends Service {
if (this.userCanChat) {
this.chatSubscriptionsManager.stopChannelsSubscriptions();
removeOnPresenceChange(this.onPresenceChangeCallback);
}
}