Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Add selector to get Posts EmbedVisible flags for RHS. #312

Conversation

sudheerDev
Copy link
Contributor

@sudheerDev sudheerDev commented Nov 17, 2017

Summary

Adding new selector for RHS posts embedVisible flags.

Checklist

  • Ran make check-style to check for style errors (required for all pull requests)
  • Added or updated unit tests (required for all new features)
  • Has redux changes (please link)

return posts.reduce((accumulatedEmbedVisibleFlags, post) => ({
...accumulatedEmbedVisibleFlags,
[post.id]: makeGetItem(StoragePrefixes.EMBED_VISIBLE + post.id, previewCollapsed.startsWith('false'))(state)
Copy link
Contributor Author

@sudheerDev sudheerDev Nov 17, 2017

Choose a reason for hiding this comment

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

@hmhealey I have to send entire state and therefore computes with every state change. Should we have makeGetItem as memorised selector which depends on state.storage instead?.

Copy link
Member

Choose a reason for hiding this comment

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

makeGetItem doesn't work with selectors with how it's currently designed, so I don't think we can use it here, but we can still definitely have this memoized properly.

What we can do though is change what the selector takes from the store so that it only takes the things that affect it: the storage state, the current user ID for the storage key prefix, and the COLLAPSE_DISPLAY preference. We'll also want to have a function that creates a selector here because it could possibly be used in multiple places, and we want to make sure each one is memoized separately so they don't clear each other's stored results. It could look something like

export function makeGetPostsEmbedVisibleObj() {
    return createSelector(
        // This could be its own function or a selector, but that's not necessary since it's really simple
        (state) => state.storage,
        // We don't need to pass in the previewCollapsed value here since we can just get it ourselves.
        // Also, we can use getBool so that we don't need to work with a string later on
        (state) => getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY),
        (state, posts) => posts,
        (storage, previewCollapsed, posts) => {
            const postsEmbedVisibleObj = {};

            for (const post of posts) {
                // You'll need to write something like makeGetItem that doesn't require the whole store to be passed in
                postsEmbedVisibleObj[post.id] = getItemFromStorage(storage, currentUserId, StoragePrefixes.EMBED_VISIBLE + post.id, previewCollapsed);
            }

            return postsEmbedVisibleObj;
        }
    );
}

That way, it'll only change when one of those exact 3 things changes, and not just any state change.

Copy link
Contributor Author

@sudheerDev sudheerDev Nov 17, 2017

Choose a reason for hiding this comment

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

I will make the changes. Thanks, this looks great 👍 .

export const getPostsEmbedVisibleObj = createSelector(
(state) => state,
(state, {posts, previewCollapsed}) => ({posts, previewCollapsed}),
Copy link
Member

Choose a reason for hiding this comment

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

Something important to note here is that this function returns a new object each time it's called, so it'll prevent memoization. Even if you were to do something like (state, props) => (props) here, props is likely changing each time this is called anyway, so it still wouldn't help. In the future though, you can break it up like this to have it work properly

createSelector(
    (state, {posts}) => posts,
    (state, {previewCollapsed}) => previewCollapsed,
    (posts, previewCollapsed) => {...}
);

As long as posts and previewCollapsed themselves don't change, it'll only be looking at their value to check if anything has changed instead of looking if the object containing them changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh ya true. That's cool

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes made changes.

return posts.reduce((accumulatedEmbedVisibleFlags, post) => ({
...accumulatedEmbedVisibleFlags,
[post.id]: makeGetItem(StoragePrefixes.EMBED_VISIBLE + post.id, previewCollapsed.startsWith('false'))(state)
Copy link
Member

Choose a reason for hiding this comment

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

makeGetItem doesn't work with selectors with how it's currently designed, so I don't think we can use it here, but we can still definitely have this memoized properly.

What we can do though is change what the selector takes from the store so that it only takes the things that affect it: the storage state, the current user ID for the storage key prefix, and the COLLAPSE_DISPLAY preference. We'll also want to have a function that creates a selector here because it could possibly be used in multiple places, and we want to make sure each one is memoized separately so they don't clear each other's stored results. It could look something like

export function makeGetPostsEmbedVisibleObj() {
    return createSelector(
        // This could be its own function or a selector, but that's not necessary since it's really simple
        (state) => state.storage,
        // We don't need to pass in the previewCollapsed value here since we can just get it ourselves.
        // Also, we can use getBool so that we don't need to work with a string later on
        (state) => getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY),
        (state, posts) => posts,
        (storage, previewCollapsed, posts) => {
            const postsEmbedVisibleObj = {};

            for (const post of posts) {
                // You'll need to write something like makeGetItem that doesn't require the whole store to be passed in
                postsEmbedVisibleObj[post.id] = getItemFromStorage(storage, currentUserId, StoragePrefixes.EMBED_VISIBLE + post.id, previewCollapsed);
            }

            return postsEmbedVisibleObj;
        }
    );
}

That way, it'll only change when one of those exact 3 things changes, and not just any state change.

@hmhealey hmhealey self-assigned this Nov 17, 2017
@hmhealey hmhealey added the 2: Dev Review Requires review by a core commiter label Nov 17, 2017
@hmhealey hmhealey added this to the v4.5.0 milestone Nov 17, 2017
@sudheerDev sudheerDev force-pushed the addSelector/getPostsEmbedVisibleObj branch from 2b46507 to b216796 Compare November 19, 2017 15:12
@sudheerDev sudheerDev force-pushed the addSelector/getPostsEmbedVisibleObj branch from b216796 to 2570d50 Compare November 19, 2017 15:24
@saturninoabril
Copy link
Member

@sudheerDev Unit test failed. Try to run make test and see where it's failing.

@sudheerDev
Copy link
Contributor Author

@saturninoabril ya I was working on top of a component branch which has a constant this commit needed. Anyway added that constant to this commit. Test cases should be fine now

Copy link
Member

@hmhealey hmhealey left a comment

Choose a reason for hiding this comment

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

Awesome, thanks for making that change. Looks good and fast now

@hmhealey hmhealey removed their assignment Nov 20, 2017
@saturninoabril saturninoabril added 4: Reviews Complete All reviewers have approved the pull request and removed 2: Dev Review Requires review by a core commiter labels Nov 20, 2017
@saturninoabril saturninoabril merged commit 1116de6 into mattermost:master Nov 20, 2017
@sudheerDev sudheerDev deleted the addSelector/getPostsEmbedVisibleObj branch November 20, 2017 16:40
@lindalumitchell lindalumitchell added the Tests/Done Release tests have been written label Nov 20, 2017
@esethna esethna added Changelog/Not Needed Does not require a changelog entry Docs/Not Needed Does not require documentation labels Dec 4, 2017
hmhealey pushed a commit that referenced this pull request Mar 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
4: Reviews Complete All reviewers have approved the pull request Changelog/Not Needed Does not require a changelog entry Docs/Not Needed Does not require documentation Tests/Done Release tests have been written
Projects
None yet
5 participants