MM-37294 MM-37296 MM-37297 MM-37495 MM-37509 CRT fixes (#5574)

* fixes MM-37294 MM-37296 MM-37297

* Added conditions to check for post & thread existence

* Update app/mm-redux/selectors/entities/threads.ts

Co-authored-by: Kyriakos Z. <3829551+koox00@users.noreply.github.com>

* type fix

* Never disabling Mark All as unread

* Added follow/unfollow message for not yet thread posts

* Test case fix for mark all as unread enabled all the time

* Removed hardcoded condition

* Fixed MM-37509

* Updated snapshot for sidebar

Co-authored-by: Kyriakos Z. <3829551+koox00@users.noreply.github.com>
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
Anurag Shivarathri 2021-07-30 11:14:01 +05:30 committed by GitHub
parent 0e0ed0b14b
commit ed1cc2a51d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 42 additions and 27 deletions

View file

@ -25,7 +25,9 @@ export function handleThreadReadChanged(msg: WebSocketMessage) {
if (msg.data.thread_id) {
const state = getState();
const thread = getThread(state, msg.data.thread_id);
if (thread) {
// Mark only following threads as read.
if (thread?.is_following) {
dispatch(
handleReadChanged(
msg.data.thread_id,

View file

@ -132,18 +132,21 @@ function ThreadFooter({actions, currentUserId, intl, location, testID, theme, th
// threadstarter should be the first one in the avatars list
const participants = React.useMemo(() => {
let isThreadStarterFound = false;
const participantIds = thread.participants.flatMap((participant) => {
if (participant.id === threadStarter?.id) {
isThreadStarterFound = true;
return [];
if (thread.participants?.length) {
let isThreadStarterFound = false;
const participantIds = thread.participants.flatMap((participant) => {
if (participant.id === threadStarter?.id) {
isThreadStarterFound = true;
return [];
}
return participant.id;
});
if (isThreadStarterFound) {
participantIds.unshift(threadStarter?.id);
}
return participant.id;
});
if (isThreadStarterFound) {
participantIds.unshift(threadStarter?.id);
return participantIds;
}
return participantIds;
return [];
}, [thread.participants, threadStarter]);
let avatars;

View file

@ -49,7 +49,7 @@ function ThreadList({haveUnreads, intl, isLoading, loadMoreThreads, listRef, mar
threadId={item}
/>
);
}, []);
}, [theme]);
const renderHeader = () => {
if (!viewingUnreads && !threadIds.length) {

View file

@ -75,7 +75,6 @@ exports[`Global Thread List Header Should render threads with functional tabs &
style={
Array [
undefined,
undefined,
]
}
/>

View file

@ -54,6 +54,7 @@ describe('Global Thread List Header', () => {
expect(markAllAsRead).toHaveBeenCalled();
});
/* @TODO: Uncomment when "mark all as read" button is disabled during no unreads.
test('Should disable mark all as read and hide dot on UNREADS tab when no unread messages are present', () => {
wrapper.setProps({
...baseProps,
@ -66,4 +67,5 @@ describe('Global Thread List Header', () => {
expect(markAllAsReadButton.exists()).toBeTruthy();
expect(markAllAsReadButton.props().disabled).toBeTruthy();
});
*/
});

View file

@ -62,13 +62,13 @@ function ThreadListHeader({haveUnreads, intl, markAllAsRead, style, testID, view
</View>
<View style={style.markAllReadIconContainer}>
<TouchableOpacity
disabled={!haveUnreads}
disabled={false/*!haveUnreads*/}
onPress={markAllAsRead}
testID={`${testID}.mark_all_read`}
>
<CompassIcon
name='playlist-check'
style={[style.markAllReadIcon, haveUnreads ? undefined : style.markAllReadIconDisabled]}
style={[style.markAllReadIcon/*, haveUnreads ? undefined : style.markAllReadIconDisabled*/]}
/>
</TouchableOpacity>
</View>

View file

@ -259,7 +259,7 @@ const Post = ({
collapsedThreadsEnabled &&
Boolean(thread) &&
post.state !== Posts.POST_DELETED &&
thread?.participants?.length
(thread?.is_following || thread?.participants?.length)
) {
footer = (
<ThreadFooter

View file

@ -4,7 +4,6 @@ exports[`ChannelsList List should match snapshot 1`] = `
<View
onLayout={[Function]}
>
<Connect(ThreadsEntry) />
<SectionList
contentContainerStyle={
Object {

View file

@ -400,8 +400,7 @@ export default class List extends PureComponent {
};
render() {
const collapsedThreadsEnabled = true;
const {testID, styles, theme} = this.props;
const {collapsedThreadsEnabled, styles, testID, theme} = this.props;
const {sections, showIndicator} = this.state;
const paddingBottom = this.listContentPadding();

View file

@ -52,7 +52,7 @@ export function getThread(state: GlobalState, threadId: $ID<UserThread>, fallbac
if (!thread || !thread?.id) {
if (fallbackFromPosts) {
const post = getPost(state, threadId);
if (post?.participants?.length) {
if (post && !post.root_id) {
const {id, is_following, reply_count, last_reply_at, participants} = post;
return {
id,

View file

@ -146,7 +146,7 @@ export function makeMapStateToProps() {
currentUserId,
isFlagged: isPostFlagged(post.id, myPreferences),
theme: getTheme(state),
thread: isCollapsedThreadsEnabled(state) && getThread(state, post.id, true),
thread: isCollapsedThreadsEnabled(state) ? getThread(state, post.id, true) : null,
};
};
}

View file

@ -14,6 +14,7 @@ import ReactionPicker from '@components/reaction_picker';
import SlideUpPanel from '@components/slide_up_panel';
import {BOTTOM_MARGIN} from '@components/slide_up_panel/slide_up_panel';
import {REACTION_PICKER_HEIGHT} from '@constants/reaction_picker';
import {CHANNEL} from '@constants/screen';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {isSystemMessage} from '@mm-redux/utils/post_utils';
import {t} from '@utils/i18n';
@ -110,19 +111,27 @@ export default class PostOptions extends PureComponent {
}
getFollowThreadOption = () => {
const {thread} = this.props;
if (!thread) {
const {location, thread} = this.props;
if (location !== CHANNEL) {
return null;
}
const key = 'follow';
let icon;
let message;
if (thread.is_following) {
if (thread?.is_following) {
icon = 'message-minus-outline';
message = {id: t('threads.unfollowThread'), defaultMessage: 'Unfollow Thread'};
if (thread?.participants?.length) {
message = {id: t('threads.unfollowThread'), defaultMessage: 'Unfollow Thread'};
} else {
message = {id: t('threads.unfollowMessage'), defaultMessage: 'Unfollow Message'};
}
} else {
icon = 'message-plus-outline';
message = {id: t('threads.followThread'), defaultMessage: 'Follow Thread'};
if (thread?.participants?.length) {
message = {id: t('threads.followThread'), defaultMessage: 'Follow Thread'};
} else {
message = {id: t('threads.followMessage'), defaultMessage: 'Follow Message'};
}
}
const onPress = this.handleToggleFollow;
return this.getOption(key, icon, message, onPress);

View file

@ -29,7 +29,7 @@ function makeMapStateToProps() {
myMember: getMyCurrentChannelMembership(state),
postIds: getPostIdsForThread(state, ownProps.rootId),
theme: getTheme(state),
thread: getThread(state, ownProps.rootId, true),
thread: collapsedThreadsEnabled ? getThread(state, ownProps.rootId, true) : null,
threadLoadingStatus: state.requests.posts.getPostThread,
};
};

View file

@ -709,9 +709,11 @@
"threads.deleted": "Original Message Deleted",
"threads.follow": "Follow",
"threads.following": "Following",
"threads.followMessage": "Follow Message",
"threads.followThread": "Follow Thread",
"threads.newReplies": "{count} new {count, plural, one {reply} other {replies}}",
"threads.replies": "{count} {count, plural, one {reply} other {replies}}",
"threads.unfollowMessage": "Unfollow Message",
"threads.unfollowThread": "Unfollow Thread",
"user.settings.display.clockDisplay": "Clock Display",
"user.settings.display.custom_theme": "Custom Theme",