FEATURE: Sync user tips status between client (#19095)
The user attributes are not updated between clients and that is a problem with user tips because the same user tip will be displayed multiple times, once for every client.
This commit is contained in:
parent
be99c3eec7
commit
c78eb60cea
|
@ -0,0 +1,29 @@
|
|||
export default {
|
||||
name: "user-tips",
|
||||
after: "message-bus",
|
||||
|
||||
initialize(container) {
|
||||
const currentUser = container.lookup("service:current-user");
|
||||
if (!currentUser) {
|
||||
return;
|
||||
}
|
||||
|
||||
const messageBus = container.lookup("service:message-bus");
|
||||
const site = container.lookup("service:site");
|
||||
|
||||
messageBus.subscribe("/user-tips", function (seenUserTips) {
|
||||
currentUser.set("seen_popups", seenUserTips);
|
||||
if (!currentUser.user_option) {
|
||||
currentUser.set("user_option", {});
|
||||
}
|
||||
currentUser.set("user_option.seen_popups", seenUserTips);
|
||||
(seenUserTips || []).forEach((userTipId) => {
|
||||
currentUser.hideUserTipForever(
|
||||
Object.keys(site.user_tips).find(
|
||||
(id) => site.user_tips[id] === userTipId
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1173,27 +1173,28 @@ const User = RestModel.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
// Hide any shown user tips.
|
||||
// Hide user tips and maybe show the next one.
|
||||
if (userTipId) {
|
||||
hideUserTip(userTipId);
|
||||
showNextUserTip();
|
||||
} else {
|
||||
hideAllUserTips();
|
||||
}
|
||||
|
||||
// Update list of seen user tips.
|
||||
let seenUserTips = this.seen_popups || [];
|
||||
if (userTipId) {
|
||||
if (seenUserTips.includes(userTips[userTipId])) {
|
||||
return;
|
||||
}
|
||||
|
||||
hideUserTip(userTipId);
|
||||
seenUserTips.push(userTips[userTipId]);
|
||||
} else {
|
||||
if (seenUserTips.includes(-1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
hideAllUserTips();
|
||||
seenUserTips = [-1];
|
||||
}
|
||||
|
||||
// Show next user tip in queue.
|
||||
showNextUserTip();
|
||||
|
||||
// Save seen user tips on the server.
|
||||
if (!this.user_option) {
|
||||
this.set("user_option", {});
|
||||
|
|
|
@ -6,6 +6,7 @@ import { settled } from "@ember/test-helpers";
|
|||
import User from "discourse/models/user";
|
||||
import pretender, { response } from "discourse/tests/helpers/create-pretender";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
import * as userTips from "discourse/lib/user-tips";
|
||||
|
||||
module("Unit | Model | user", function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
@ -199,12 +200,11 @@ module("Unit | Model | user", function (hooks) {
|
|||
test("hideUserTipForever() makes a single request", async function (assert) {
|
||||
const site = getOwner(this).lookup("service:site");
|
||||
site.set("user_tips", { first_notification: 1 });
|
||||
|
||||
const store = getOwner(this).lookup("service:store");
|
||||
const user = store.createRecord("user", { username: "test" });
|
||||
const user = store.createRecord("user", { username: "eviltrout" });
|
||||
|
||||
let requestsCount = 0;
|
||||
pretender.put("/u/test.json", () => {
|
||||
pretender.put("/u/eviltrout.json", () => {
|
||||
requestsCount += 1;
|
||||
return response(200, {
|
||||
user: {
|
||||
|
@ -221,4 +221,30 @@ module("Unit | Model | user", function (hooks) {
|
|||
await user.hideUserTipForever("first_notification");
|
||||
assert.strictEqual(requestsCount, 1);
|
||||
});
|
||||
|
||||
test("hideUserTipForever() can hide the user tip", async function (assert) {
|
||||
const site = getOwner(this).lookup("service:site");
|
||||
site.set("user_tips", { first_notification: 1 });
|
||||
const store = getOwner(this).lookup("service:store");
|
||||
const user = store.createRecord("user", { username: "eviltrout" });
|
||||
|
||||
const hideSpy = sinon.spy(userTips, "hideUserTip");
|
||||
const showNextSpy = sinon.spy(userTips, "showNextUserTip");
|
||||
await user.hideUserTipForever("first_notification");
|
||||
|
||||
assert.ok(hideSpy.calledWith("first_notification"));
|
||||
assert.ok(showNextSpy.calledWith());
|
||||
});
|
||||
|
||||
test("hideUserTipForever() can hide all the user tips", async function (assert) {
|
||||
const site = getOwner(this).lookup("service:site");
|
||||
site.set("user_tips", { first_notification: 1 });
|
||||
const store = getOwner(this).lookup("service:store");
|
||||
const user = store.createRecord("user", { username: "eviltrout" });
|
||||
|
||||
const hideAllSpy = sinon.spy(userTips, "hideAllUserTips");
|
||||
await user.hideUserTipForever();
|
||||
|
||||
assert.ok(hideAllSpy.calledWith());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -248,6 +248,13 @@ class UserUpdater
|
|||
user_notification_schedule.create_do_not_disturb_timings(delete_existing: true) :
|
||||
user_notification_schedule.destroy_scheduled_timings
|
||||
end
|
||||
if attributes.key?(:seen_popups) || attributes.key?(:skip_new_user_tips)
|
||||
MessageBus.publish(
|
||||
'/user-tips',
|
||||
user.user_option.seen_popups,
|
||||
user_ids: [user.id]
|
||||
)
|
||||
end
|
||||
DiscourseEvent.trigger(:user_updated, user)
|
||||
end
|
||||
|
||||
|
|
|
@ -526,16 +526,33 @@ RSpec.describe UserUpdater do
|
|||
end
|
||||
|
||||
context 'when skip_new_user_tips is edited' do
|
||||
it 'updates all fields' do
|
||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: true)
|
||||
it 'updates seen_popups too' do
|
||||
messages = MessageBus.track_publish('/user-tips') do
|
||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: true)
|
||||
end
|
||||
|
||||
expect(user.user_option.skip_new_user_tips).to eq(true)
|
||||
expect(user.user_option.seen_popups).to eq([-1])
|
||||
expect(messages.map(&:data)).to contain_exactly([-1])
|
||||
|
||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: false)
|
||||
messages = MessageBus.track_publish('/user-tips') do
|
||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: false)
|
||||
end
|
||||
|
||||
expect(user.user_option.skip_new_user_tips).to eq(false)
|
||||
expect(user.user_option.seen_popups).to eq(nil)
|
||||
expect(messages.map(&:data)).to contain_exactly(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when seen_popups is edited' do
|
||||
it 'publishes a message' do
|
||||
messages = MessageBus.track_publish('/user-tips') do
|
||||
UserUpdater.new(Discourse.system_user, user).update(seen_popups: [1])
|
||||
end
|
||||
|
||||
expect(user.user_option.seen_popups).to eq([1])
|
||||
expect(messages.map(&:data)).to contain_exactly([1])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue