Conversation
Generated by 🚫 dangerJS |
…er than only community info.
…a bit more to do yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM, only concern is the Thread.reactions
schema as noted below. Let's get something better in there that's not like the Message.reactions
one, then I'm good with the backend side of things here apart from the nits!
api/models/threadReaction.js
Outdated
import { events } from 'shared/analytics'; | ||
import { trackQueue } from 'shared/bull/queues'; | ||
|
||
type ReactionType = 'like'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this should probably be ThreadReactionType
?
}, | ||
}); | ||
|
||
sendThreadReactionNotificationQueue.add({ threadReaction: thisReaction, userId }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably not ideal? If I'm reading this correctly, it would mean that if I spam-click the thread reaction button you'll be sent millions of notifications, one for each click. We should only ever send one of 'em?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is handled in athena. It works by looking up a previous notification of the same type on the same entity in the previous 30mins, then will de-duplicate actors. So the result is that it will mark the notification as "unread" for the thread author, but will not actually insert multiple notifications unless there is a 30 min gap in between.
api/types/Thread.js
Outdated
@@ -97,13 +98,24 @@ const Thread = /* GraphQL */ ` | |||
filesToUpload: [Upload] | |||
} | |||
|
|||
input AddThreadReactionInput { | |||
threadId: ID! | |||
type: ReactionTypes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should be ThreadReactionTypes
debug('get thread'); | ||
|
||
// make sure that the person who left the original message still has notification permissions in this thread. We have to check the threadtype to determine if the reaction was left in a story thread or a direct message thread | ||
// TODO: In the future we'll want reactions in direct message threads to trigger push notifications, but for now it introduces too much complexity so we just say false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this todo doesn't make any sense, you can't react to a dm thread?
const thread = await getThreadById(updatedNotification.context.id); | ||
|
||
// make sure that the person who left the original message still has notification permissions in this thread. We have to check the threadtype to determine if the reaction was left in a story thread or a direct message thread | ||
// TODO: In the future we'll want reactions in direct message threads to trigger push notifications, but for now it introduces too much complexity so we just say false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this todo doesn't make any sense, you can't react to a dm thread?
api/types/Thread.js
Outdated
@@ -54,6 +54,7 @@ const Thread = /* GraphQL */ ` | |||
attachments: [Attachment] | |||
watercooler: Boolean | |||
currentUserLastSeen: Date @cost(complexity: 1) | |||
reactions: ReactionData @cost(complexity: 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to veto using the same schema as the message reactions because it doesn't let us show which users liked the thing. (you only see it in the notifications, but nobody else can see/check) Let's change the return type here to include that information somehow, (open to ideas) so we can in the future show who liked a thread or not in the UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to change this to be a separate type ThreadReactions
which will expose:
count: Int
hasReacted: Boolean
reactors: [User]
Or something like that - we can actually extend the message reactions to have the same data model, but let's keep message reactions and thread reactions as separately defined types in case they diverge in the future.
…ntil you pass the actionbar probably?
Took a while, but finally got this working. @mxstbr the one trouble I ran into was debouncing the
Any chance you could take a look? Without the debounce people's machines are gonna get real real hot. |
Also @uberbryn @mxstbr - if you want to pull this and try it out, let me know what you think. In my opinion it's very very distracting to have this header jump in and out every time you change the thread in the inbox view. But it seems to be quite a challenge to work around that since we're doing so much scroll position handling every time a thread is changed. |
Would be cool for it to be more chill when we jump your scroll position as you mentioned, but I also think it's fine as is - it really wouldn't have bothered me other than that you mentioned it. Other solution I could think of would be transitioning it from 0 opacity to 1 so the motion isn't jumpy, but I really don't think it's that big of a deal. Would prefer shipping and refining later. Great work, bud! Thanks for grabbing that! |
Will take a look! |
src/views/thread/container.js
Outdated
// enable the `bannerIsVisible` state to slide the thread context banner | ||
// in from the top of the screen | ||
const scrollOffset = e.target.scrollTop; | ||
this.setState({ scrollOffset }, () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be putting the scroll offset (which changes every single frame you scroll) into the state, this is what's causing the issues. This isn't even necessary, just don't put it into the state, compare scrollOffset
against threadDetailHeight
and only set the state if it changes. That way you don't even need to debounce which is kinda annoying for this behavior
I'm taking a look at refactoring this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs an optimistic update on the like click—feels bad rn on slow networks/with the remote server overhead. Will also tackle.
…re-renders @brianlovin see how I made it so we only `setState` once the state actually changes? This means we barely re-render the React side of things, which makes this much much much more performant! 👌
type ThreadReactions { | ||
count: Int! | ||
hasReacted: Boolean | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though you split 'em up, this is still the same schema as the message reactions? I thought we agreed that we should do this one right from the start (to one that let's us show who liked a thread) so we wouldn't have to migrate to a different one in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, see comment below.
Nevermind, played around with this a bit and it's a pain in the butt. Let's not do this for now 😅 So the last bit here is coming up with a nicer schema that let's us show who liked a thread, right? |
Hm, the schema will be:
Right? We just add a field inside that type.
But again, all of this can be added later. Querying would not change except adding the field to the graphql query and extracting it on the frontend with |
Let me see if I can handle optimistic update real quick |
Optimistic updating is pushed, @mxstbr this is ready for a final review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That schema actually makes a lot of sense. This LGTM, let's ship it?!
LET'S SHIP IT! Gonna put it on alpha, run the migration, test, then do a prod cut. |
Status
Deploy after merge (delete what needn't be deployed)
Run database migrations (delete if no migration was added)
YES
Release notes for users (delete if codebase-only change)
Related issues (delete if you don't know of any)
Closes #