Skip to content

unread [nfc]: Add getUnreadCountForTopic #4805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 18, 2021

Conversation

gnprice
Copy link
Member

@gnprice gnprice commented Jun 16, 2021

This is a quick refactoring inspired by #4635 (comment) .

There's a number of useful things we could do further in this direction, but stopping here for now in order to get this out.

Copy link
Contributor

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This LGTM overall; see one small question below.

@@ -40,6 +40,13 @@ export const getUnreadHuddles = (state: GlobalState): UnreadHuddlesState => stat

export const getUnreadMentions = (state: GlobalState): UnreadMentionsState => state.unread.mentions;

/** The total number of unreads in the given topic. */
export const getUnreadCountForTopic = (
unread: UnreadState,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it fine for a selector to take a substate (like UnreadState) as the input state, or should all selectors start with GlobalState?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, perhaps calling this a "selector" is confusing and I should label it something else. Maybe "getter"?

The reason I want it taking just the unread state is so that we can conveniently use it in a context like #4635, in code where we have a BackgroundData style of object but don't have the whole Redux state.

More generally, a direction I'm interested in taking our data-model code is toward having each subsystem's model be more of a self-contained thing with its own identity and interface, vs. the status quo which kind of tries (but inconsistently so, because this doesn't really work if you try to push it hard) to treat them all as undifferentiated implementation details of the global state. For example, we'd have the whole "unreads" model as one such subsystem. So having a getter like this directly on that model's state is a small experiment in that direction.

Copy link
Contributor

@chrisbobbe chrisbobbe Jun 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name "selector" is probably fine, and the use case makes sense. Thanks for explaining, and I'm excited to see progress in getting our data-model code structured more sensibly. 🙂

We'd call both rootReducer and messagesReducer "reducers", and I think it's fine to call both this function and those that take GlobalState "selectors".

gnprice added 4 commits June 18, 2021 14:31
This will let us start passing around the unread state as a whole,
instead of its various pieces like the part for streams or 1:1 PMs.

That in turn will help us start to better encapsulate the specifics
of the unread state's data structures, which will make it easier to
modify them.
This will let us get this information in a convenient way from code
that's entirely outside of the unreads code -- like this call site,
in `getTopicsForStream` which is a UI-oriented selector that exists
to drive the topics-list screen -- without having to dig into the
details of the data structures we use for the unreads data.

It's possible to get a similar effect already by invoking
`getUnreadCountForNarrow`.  But (a) that interferes with the caching
on that selector, which is really meant to be used only for the one
current narrow that's foregrounded in the UI; and (b) that requires
an entire `GlobalState` object, whereas we'd like to be able to get
this effect from code that has only some relevant pieces of the state,
in the spirit of `BackgroundData`.

Because we generally say "selector" to mean something that requires
the global state as its input, we file this function under the more
general term "getter".
This is a bit cleaner anyway than using three different selectors
for different pieces; plus it'll let us use the new, encapsulated
`getUnreadCountForTopic`.
Now this spot where we look into the details of the unreads data
structure is encapsulated inside the unreads model.
@gnprice
Copy link
Member Author

gnprice commented Jun 18, 2021

Thanks for the review! Revision pushed.

@chrisbobbe chrisbobbe merged commit 6a1744c into zulip:master Jun 18, 2021
@chrisbobbe
Copy link
Contributor

Great, thanks! Merged.

@gnprice gnprice deleted the pr-unread-count branch June 19, 2021 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants