From 29240b9c6f4626fdccbc7ca5fed2bcbbfa21e48a Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 6 Jun 2019 15:15:40 -0400 Subject: [PATCH] MM-16061 Keep unread channels in place on Tablets (#2865) --- app/actions/views/channel.js | 1 + .../sidebars/main/channels_list/list/index.js | 9 +++-- app/constants/view.js | 9 +++++ app/reducers/views/channel.js | 40 +++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js index c6903ad6b..511f5a8b6 100644 --- a/app/actions/views/channel.js +++ b/app/actions/views/channel.js @@ -394,6 +394,7 @@ export function handleSelectChannel(channelId, fromPushNotification = false) { { type: ViewTypes.SELECT_CHANNEL_WITH_MEMBER, data: channelId, + channel, member, }, ])); diff --git a/app/components/sidebars/main/channels_list/list/index.js b/app/components/sidebars/main/channels_list/list/index.js index 5e1ddb673..adb6f31a7 100644 --- a/app/components/sidebars/main/channels_list/list/index.js +++ b/app/components/sidebars/main/channels_list/list/index.js @@ -17,13 +17,13 @@ import {memoizeResult} from 'mattermost-redux/utils/helpers'; import {isAdmin as checkIsAdmin, isSystemAdmin as checkIsSystemAdmin} from 'mattermost-redux/utils/user_utils'; import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; -import {SidebarSectionTypes} from 'app/constants/view'; +import {DeviceTypes, ViewTypes} from 'app/constants'; import List from './list'; const filterZeroUnreads = memoizeResult((sections) => { return sections.filter((s) => { - if (s.type === SidebarSectionTypes.UNREADS) { + if (s.type === ViewTypes.SidebarSectionTypes.UNREADS) { return s.items.length > 0; } return true; @@ -38,11 +38,12 @@ function mapStateToProps(state) { const isAdmin = checkIsAdmin(roles); const isSystemAdmin = checkIsSystemAdmin(roles); const sidebarPrefs = getSidebarPreferences(state); - const unreadChannelIds = getSortedUnreadChannelIds(state, null); + const lastUnreadChannel = DeviceTypes.IS_TABLET ? state.views.channel.keepChannelIdAsUnread : null; + const unreadChannelIds = getSortedUnreadChannelIds(state, lastUnreadChannel); const favoriteChannelIds = getSortedFavoriteChannelIds(state); const orderedChannelIds = filterZeroUnreads(getOrderedChannelIds( state, - null, + lastUnreadChannel, sidebarPrefs.grouping, sidebarPrefs.sorting, true, // The mobile app should always display the Unreads section regardless of user settings (MM-13420) diff --git a/app/constants/view.js b/app/constants/view.js index b885a87e9..42563da24 100644 --- a/app/constants/view.js +++ b/app/constants/view.js @@ -20,6 +20,13 @@ export const SidebarSectionTypes = { ALPHA: 'alpha', }; +export const NotificationLevels = { + DEFAULT: 'default', + ALL: 'all', + MENTION: 'mention', + NONE: 'none', +}; + const ViewTypes = keyMirror({ DATA_CLEANUP: null, SERVER_URL_CHANGED: null, @@ -109,4 +116,6 @@ export default { PROFILE_PICTURE_SIZE: 32, DATA_SOURCE_USERS: 'users', DATA_SOURCE_CHANNELS: 'channels', + NotificationLevels, + SidebarSectionTypes, }; diff --git a/app/reducers/views/channel.js b/app/reducers/views/channel.js index 8fd862ee3..87fd7f930 100644 --- a/app/reducers/views/channel.js +++ b/app/reducers/views/channel.js @@ -6,6 +6,7 @@ import { ChannelTypes, FileTypes, PostTypes, + UserTypes, } from 'mattermost-redux/action_types'; import {ViewTypes} from 'app/constants'; @@ -348,6 +349,44 @@ function lastChannelViewTime(state = {}, action) { } } +function keepChannelIdAsUnread(state = null, action) { + switch (action.type) { + case ViewTypes.SELECT_CHANNEL_WITH_MEMBER: { + const member = action.member; + const channel = action.channel; + + if (!member || !channel) { + return state; + } + + const msgCount = channel.total_msg_count - member.msg_count; + const hadMentions = member.mention_count > 0; + const hadUnreads = member.notify_props.mark_unread !== ViewTypes.NotificationLevels.MENTION && msgCount > 0; + + if (hadMentions || hadUnreads) { + return { + id: member.channel_id, + hadMentions, + }; + } + + return null; + } + + case ViewTypes.RECEIVED_FOCUSED_POST: { + if (state && action.channelId !== state.id) { + return null; + } + return state; + } + + case UserTypes.LOGOUT_SUCCESS: + return null; + default: + return state; + } +} + export default combineReducers({ displayName, drafts, @@ -360,4 +399,5 @@ export default combineReducers({ retryFailed, loadMorePostsVisible, lastChannelViewTime, + keepChannelIdAsUnread, });