FIX: Background like count update didn't account for own user actions (#16688)

This fixes a corner case of the perf optimization in d4e35f5.

When you have the the same post showing in multiple tab/devices and like
said post in one place, we updated the like count but didn't flip the
`acted` bool in the front-end. This caused a small visual desync.

Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
This commit is contained in:
Rafael dos Santos Silva 2022-05-09 17:23:39 -03:00 committed by GitHub
parent bc8968fd12
commit 919f71537e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 19 deletions

View File

@ -1712,9 +1712,15 @@ export default Controller.extend(bufferedProperty("model"), {
.then(() => refresh({ id: data.id, refreshLikes: true }));
break;
}
case "liked": {
case "liked":
case "unliked": {
postStream
.triggerLikedPost(data.id, data.likes_count)
.triggerLikedPost(
data.id,
data.likes_count,
data.user_id,
data.type
)
.then(() => refresh({ id: data.id, refreshLikes: true }));
break;
}

View File

@ -847,12 +847,12 @@ export default RestModel.extend({
return resolved;
},
triggerLikedPost(postId, likesCount) {
triggerLikedPost(postId, likesCount, userID, eventType) {
const resolved = Promise.resolve();
const post = this.findLoadedPost(postId);
if (post) {
post.updateLikeCount(likesCount);
post.updateLikeCount(likesCount, userID, eventType);
this.storePost(post);
}

View File

@ -355,21 +355,18 @@ const Post = RestModel.extend({
}
},
updateLikeCount(count) {
updateLikeCount(count, userId, eventType) {
let ownLike = User.current()?.id === userId && eventType === "liked";
let current_actions_summary = this.get("actions_summary");
let likeActionID = Site.current().post_action_types.find(
(a) => a.name_key === "like"
).id;
const newActionObject = { id: likeActionID, count, acted: ownLike };
if (!this.actions_summary.find((entry) => entry.id === likeActionID)) {
let json = Post.munge({
id: this.id,
actions_summary: [
{
id: likeActionID,
count,
},
],
actions_summary: [newActionObject],
});
this.set(
"actions_summary",
@ -378,11 +375,12 @@ const Post = RestModel.extend({
this.set("actionByName", json.actionByName);
this.set("likeAction", json.likeAction);
} else {
this.actions_summary.find(
(entry) => entry.id === likeActionID
).count = count;
this.actionByName["like"] = count;
this.likeAction.count = count;
Object.assign(
this.actions_summary.find((entry) => entry.id === likeActionID),
newActionObject
);
Object.assign(this.actionByName["like"], newActionObject);
Object.assign(this.likeAction, newActionObject);
}
},

View File

@ -161,7 +161,7 @@ private
def notify_subscribers
if @post_action_name == :like
@post.publish_change_to_clients! :liked, { likes_count: @post.like_count + 1 }
@post.publish_change_to_clients! :liked, { likes_count: @post.like_count + 1, user_id: @created_by.id }
elsif self.class.notify_types.include?(@post_action_name)
@post.publish_change_to_clients! :acted
end

View File

@ -65,7 +65,7 @@ protected
def notify_subscribers
name = PostActionType.types[@post_action_type_id]
if name == :like
@post.publish_change_to_clients!(:liked, { likes_count: @post.like_count })
@post.publish_change_to_clients!(:unliked, { likes_count: @post.like_count, user_id: @destroyed_by.id })
elsif self.class.notify_types.include?(name)
@post.publish_change_to_clients!(:acted)
end

View File

@ -60,6 +60,19 @@ describe PostActionCreator do
expect(result.post_action.post_action_type_id).to eq(like_type_id)
end
it 'notifies subscribers' do
expect(post.reload.like_count).to eq(0)
messages = MessageBus.track_publish do
PostActionCreator.new(user, post, like_type_id).perform
end
message = messages.last.data
expect(message[:type]).to eq(:liked)
expect(message[:likes_count]).to eq(1)
expect(message[:user_id]).to eq(user.id)
end
it 'does not create an invalid post action' do
result = PostActionCreator.new(user, nil, like_type_id).perform
expect(result.failed?).to eq(true)

View File

@ -26,8 +26,9 @@ describe PostActionDestroyer do
end
message = messages.last.data
expect(message[:type]).to eq(:liked)
expect(message[:type]).to eq(:unliked)
expect(message[:likes_count]).to eq(0)
expect(message[:user_id]).to eq(user.id)
end
end