FIX: ensure presence channels 'leave' correctly when the tab is backgrounded

Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
Loudghiri Ahmed 2023-07-31 10:41:56 +02:00 committed by GitHub
parent 5f0bc4557f
commit 3232c83bf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 2 deletions

View File

@ -266,6 +266,7 @@ export default class PresenceService extends Service {
this._presentProxies = new Map();
this._subscribedProxies = new Map();
this._initialDataRequests = new Map();
this._previousPresentButInactiveChannels = new Set();
if (this.currentUser) {
window.addEventListener("beforeunload", this._beaconLeaveAll);
@ -512,6 +513,7 @@ export default class PresenceService extends Service {
try {
const presentChannels = [];
const presentButInactiveChannels = new Set();
const channelsToLeave = queue
.filter((e) => e.type === "leave")
.map((e) => e.channel);
@ -524,11 +526,19 @@ export default class PresenceService extends Service {
) {
presentChannels.push(channelName);
} else {
channelsToLeave.push(channelName);
presentButInactiveChannels.add(channelName);
if (!this._previousPresentButInactiveChannels.has(channelName)) {
channelsToLeave.push(channelName);
}
}
}
this._previousPresentButInactiveChannels = presentButInactiveChannels;
if (queue.length === 0 && presentChannels.length === 0) {
if (
queue.length === 0 &&
presentChannels.length === 0 &&
channelsToLeave.length === 0
) {
return;
}

View File

@ -426,6 +426,43 @@ module("Unit | Service | presence | entering and leaving", function (hooks) {
);
});
test("updates the server presence after going idle", async function (assert) {
const presenceService = getOwner(this).lookup("service:presence");
presenceService.currentUser = currentUser();
const channel = presenceService.getChannel("/test/ch1");
await channel.enter();
requests.pop(); // Throw away this request
setTestPresence(false);
await presenceService._updateServer();
assert.strictEqual(
requests.length,
1,
"updated the server after going idle"
);
let request = requests.pop();
assert.true(
request.getAll("leave_channels[]").includes("/test/ch1"),
"left ch1"
);
// Go back online
setTestPresence(true);
await presenceService._updateServer();
assert.strictEqual(
requests.length,
1,
"updated the server after going back online"
);
request = requests.pop();
assert.true(
request.getAll("present_channels[]").includes("/test/ch1"),
"rejoined ch1"
);
});
test("handles the onlyWhileActive flag", async function (assert) {
const presenceService = getOwner(this).lookup("service:presence");
presenceService.currentUser = currentUser();