## Issue
When comments are refreshed, each `Comment` gets rendered 4-5 times due to reference invalidation for `othersReacts` (the data didn't actually change).
## Change
For selectors without transformation, there is no need to memoize using `createSelector` -- just access it directly. Also, don't do things like `return a[id] || {}` in a reducer, because the reference to the empty object will be different on each call.
Always return directly from the state so that the same reference is returned.
This simple change avoided the wasted resources needed for `createSelector`, and reduced to render to just 2 (initial render, and when reactions are fetched).
## Issue
Components render unnecessarily due to reference invalidation from `selectMutedChannels` selector.
## Notes
`selectMutedChannels` run and return a new reference each time the app gains focus. `createSelector` will not help in this case, because we are indeed invalidating the data in the store in `USER_STATE_POPULATE`.
## Changes
- Don't update the state if the array is identical in content.
- Fixed `selectMutedChannels` to return the reference from the store, so `createSelector` is not needed.
- Also, the filtering is not needed because we've already done it in the reducer.
## Comments
I've done some profiling on large blocklists. The time needed for the array comparison is still an order magnitude lower than the time needed to render all the Components that got incorrectly marked by this.
The ideal solution is for the sync code to return a hash or timestamp of the array, so that we can compare that instead of the array.
I think this the best solution so far, at the expense of a slight delay in scrolling if the network call stalls.
- Added "fetching by ID" state so that we don't need to use the ugly N-retries method.
- `scrollIntoView` doesn't work if the element is already in the viewport, and the `scrollBy` adjustment doesn't take into account the y-position restoration that we perform on certain type of pages. Use `window.scrollTo` instead and taking into account current scroll position.
## Preamble
- The app-side uses a cached blocklist, so when a Timeout expires, it doesn't know that the ban has been lifted.
- Meanwhile, we are doing extra comment filtering using this blocklist (so that we don't see comments that we have blocked, regardless of whose claim we are viewing).
## Issue
In a livestream, if a new message from an ex-offender comes in after their ban has been lifted, we do get the websocket message but it's being filtered out locally as mentioned above. So, the msg ended up being visible for everyone except the owner.
## Fix (band aid)
- Don't run the extra filter if the claim we are viewing is ours -- commentron would have filtered it for us anyways, and is the right logic to use even before this Timeout feature is introduced.
- For the case of Timeout, this only serves as a band-aid until Commentron Issue 80 is available for us to detect the ban has been lifted. This is because it doesn't handle the case where I am a viewer and I decided to timeout someone for a few minutes. Because I am not the owner of the claim, the offender will continue to be blocked due to the same issue mentioned above.
Previously, we decide when to display "Show More" based on the current fetched reply count vs. total replies in Commentron. It was already troublesome as `comment.List` and `comment.replies` give different values (one includes blocked content, while another does not).
Now, we are further filtering the list with Commentron blocklists (personal, admin, moderator), so it is not feasible to run the logic based on reply count.
## Solution
- Keep track of number of remaining pages instead and use that to determine when to display "Show More".
- While it doesn't solve the "Show N replies" mismatch (YT has this problem too), it prevents the button from lingering.
- In the event that all replies are blocked, just show an empty space (same as YT). I didn't like the previous version that cluttered the space with "comment(s) blocked".
## Issue
When you block Channel-X, Channel-X's comments will still be visible on someone else's content. This feels odd.
## Change
In addition to the blacklist, filter-list and muted-list, we now include the Commentron blocklists (personal, admin, moderator) when filtering out comments.
## Specifics
`makeSelectCommentsForUri`, `makeSelectTopLevelCommentsForUri` and `makeSelectRepliesForParentId` all perform the same filtering code. Factor that out to `makeSelectFilteredComments` and add the Commentron lists into the mix.
## Downsides
This probably adds to the already-high CPU usage in rendering comments.
## Ticket
6879: Previously pinned livestream comments show as latest
## Issue
`comment.List` will always display the pinned comment first, hence the problem when the chat is refreshed.
## Approach
Completely split pinned comments from top-level comments in the Reducer, and the let the GUI (e.g. regular comments, livestream comments) decide how they want to display it.
For the case of livestream, there is no need to repeat the pinned comments in the regular chat area, since there is a dedicated area on top.
## General
- `setting.List`: returns full creator settings. Requires signature (i.e. you own the channel)
- `setting.Get`: returns a public subset of the creator settings. No signature required, and it is mainly used by the GUI to determine the constraints of a channel (e.g. comments enabled? min tip requirements? etc.). Does not include private settings like "blocked words list".
`doFetchCreatorSettings` will handle both of these. Clients that uses the stashed results (`settingsByChannelId`) just needs to be aware the result might not contain everything, depending on whether you own the channel or not.
## Misc Related Changes
- Finally fix the reducer for COMMENT_FETCH_SETTINGS_COMPLETED to not purge the data on each call.
- Change `doFetchCreatorSettings` to operate on a single channel instead of multiple. We ended up not using the multple mode anyway, so it was wasteful code trying to batch the promises.
- `commentsDisabledChannelIds` is no longer needed. Previously, this was created just to differentiate between Creator (full) and Channel (subset) settings. It's cleaner to just use one object, so eliminated this.
- Remove unused 'commentingEnabled'.
## Aside
- There are now 2 ways to know if a channel has disabled comments: (1) from `comment.list` and `setting.Get|List`. Both of them updates `settingsByChannelId`, so it'll still be a single place for the GUI to check against.
## Issue
- `Comment.replies` currently represent all replies, while `comment.List` returns a filtered version, so the actual replies could be less.
- The actual replies is represented by `total_filtered_items`, but we only get that after making a fetch. So, users could click "Show more" but get nothing.
## Fix
- Stop showing "Show more" based on `total_filtered_items`.
- If there is a balance, display 1 dummy comment to represent all blocked replies. This handles the case of "Show more" being displayed but ended up with 0 replies if all replies were blocked.
## Future
Note that `Comment.replies` might be changed to represented filtered comments in the near future (refer to Beamer), so the GUI is made such that the dummy just won't appear when that change happens.
## Issue
Closes 6159 "Support Comments Enabled/Disabled for comment.List API"
## New behavior
- `disable-comments` tag will block the comments component entirely.
- `settings.commentsEnabled`:
- When false, will pause comment fetching, posting and replying.
- Any already-fetched comments will stay on screen (unless user reloads/F5).
* initial support for block/mute
* hide blocked + muted content everywhere
* add info message for blocked/muted characteristics
* sort blocked list by most recent block first
* add 'blocked' message on channel page for channels that you have blocked
* cleanup
* delete unused files
* always pass mute/block list to claim_search on homepage
* PR cleanup