mattermost-mobile/app/components/global_threads/global_threads.tsx
Anurag Shivarathri fc929891ea
MM-37485 MM-37602 MM-37610 MM-37684 MM-37719 MM-37522 MM-37720 App crash, Sync issue fixes (#5612)
Summary
Fixes app crash on opening channel header
Fixes app crash on opening permalink from permalink screen
Fixes showing duplicates channels while searching in "Jump to..."
Fixes auto following the thread on opening the thread view when there are unreads
Fixes updation of threads state (Read/Unread/Deleted) of already loaded threads
Fixes counter showing as blank due to threads sync issue
Doesn't show Follow Thread/Message when CRT is not enabled

Ticket Link
https://mattermost.atlassian.net/browse/MM-37485
https://mattermost.atlassian.net/browse/MM-37602
https://mattermost.atlassian.net/browse/MM-37610
https://mattermost.atlassian.net/browse/MM-37684
https://mattermost.atlassian.net/browse/MM-37719
https://mattermost.atlassian.net/browse/MM-37522
https://mattermost.atlassian.net/browse/MM-37720

Device Information
This PR was tested on: iOS 14.5
2021-08-11 15:56:38 +05:30

128 lines
4.5 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {injectIntl, intlShape} from 'react-intl';
import {Alert, FlatList} from 'react-native';
import ThreadList from './thread_list';
import type {ActionResult} from '@mm-redux/types/actions';
import type {Theme} from '@mm-redux/types/preferences';
import type {Team} from '@mm-redux/types/teams';
import type {ThreadsState, UserThread} from '@mm-redux/types/threads';
import type {UserProfile} from '@mm-redux/types/users';
import type {$ID} from '@mm-redux/types/utilities';
type Props = {
actions: {
getThreads: (userId: $ID<UserProfile>, teamId: $ID<Team>, before?: $ID<UserThread>, after?: $ID<UserThread>, perPage?: number, deleted?: boolean, unread?: boolean) => Promise<ActionResult>;
handleViewingGlobalThreadsAll: () => void;
handleViewingGlobalThreadsUnreads: () => void;
markAllThreadsInTeamRead: (userId: $ID<UserProfile>, teamId: $ID<Team>) => void;
};
allThreadIds: $ID<UserThread>[];
intl: typeof intlShape;
teamId: $ID<Team>;
theme: Theme;
threadCount: ThreadsState['counts'][$ID<Team>];
unreadThreadIds: $ID<UserThread>[];
userId: $ID<UserProfile>;
viewingUnreads: boolean;
}
function GlobalThreadsList({actions, allThreadIds, intl, teamId, theme, threadCount, unreadThreadIds, userId, viewingUnreads}: Props) {
const ids = viewingUnreads ? unreadThreadIds : allThreadIds;
const haveUnreads = threadCount?.total_unread_threads > 0;
const listRef = React.useRef<FlatList>(null);
const [isLoading, setIsLoading] = React.useState<boolean>(true);
const scrollToTop = () => {
listRef.current?.scrollToOffset({offset: 0});
};
const loadThreads = async (before = '', after = '', unread = false) => {
if (!isLoading) {
setIsLoading(true);
}
await actions.getThreads(userId, teamId, before, after, undefined, false, unread);
setIsLoading(false);
};
React.useEffect(() => {
// Loads on mount, Loads on team change
scrollToTop();
loadThreads('', '', viewingUnreads);
}, [teamId, viewingUnreads]);
// Prevent from being called when an active request is pending.
const loadMoreThreads = async () => {
if (
!isLoading &&
ids.length &&
threadCount.total
) {
// Check if we have more threads to load.
if (viewingUnreads) {
if (threadCount.total_unread_threads === unreadThreadIds.length) {
return;
}
} else if (threadCount.total === allThreadIds.length) {
return;
}
// Get the last thread, send request for threads after this thread.
const lastThreadId = ids[ids.length - 1];
await loadThreads(lastThreadId, '', viewingUnreads);
}
};
const markAllAsRead = () => {
Alert.alert(
intl.formatMessage({
id: 'global_threads.markAllRead.title',
defaultMessage: 'Are you sure you want to mark all threads as read?',
}),
intl.formatMessage({
id: 'global_threads.markAllRead.message',
defaultMessage: 'This will clear any unread status for all of your threads shown here',
}),
[{
text: intl.formatMessage({
id: 'global_threads.markAllRead.cancel',
defaultMessage: 'Cancel',
}),
style: 'cancel',
}, {
text: intl.formatMessage({
id: 'global_threads.markAllRead.markRead',
defaultMessage: 'Mark read',
}),
style: 'default',
onPress: () => {
actions.markAllThreadsInTeamRead(userId, teamId);
},
}],
);
};
return (
<ThreadList
haveUnreads={haveUnreads}
isLoading={isLoading}
listRef={listRef}
loadMoreThreads={loadMoreThreads}
markAllAsRead={markAllAsRead}
testID={'global_threads'}
theme={theme}
threadIds={ids}
viewingUnreads={viewingUnreads}
viewAllThreads={actions.handleViewingGlobalThreadsAll}
viewUnreadThreads={actions.handleViewingGlobalThreadsUnreads}
/>
);
}
export default injectIntl(GlobalThreadsList);