mattermost-mobile/app/mm-redux/actions/threads.ts
Daniel Espino García 4c8594d330
Add linter rules for import order and type member delimiters (#5514)
* Add linter rules for import order and type member delimiters

* Remove unneeded group

* Group all app/* imports before the internal imports

* Move app/ imports before parent imports

* Separate @node_modules imports into a different group

* Substitute app paths by aliases

* Fix @node_modules import order and add test related modules

* Add aliases for types and test, and group import types
2021-07-23 11:06:04 +02:00

277 lines
8.8 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Client4} from '@client/rest';
import {ViewTypes} from '@constants';
import {ThreadTypes, PostTypes, UserTypes} from '@mm-redux/action_types';
import {getCurrentUserId} from '@mm-redux/selectors/entities/common';
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
import {getThread as getThreadSelector, getThreadTeamId} from '@mm-redux/selectors/entities/threads';
import {ActionResult, batchActions, DispatchFunc, GenericAction, GetStateFunc} from '@mm-redux/types/actions';
import {logError} from './errors';
import {forceLogoutIfNecessary} from './helpers';
import {getMissingProfilesByIds} from './users';
import type {Post} from '@mm-redux/types/posts';
import type {UserThread, UserThreadList} from '@mm-redux/types/threads';
export function getThreads(userId: string, teamId: string, before = '', after = '', perPage = ViewTypes.CRT_CHUNK_SIZE, deleted = false, unread = true, since = 0) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
let userThreadList: UserThreadList;
try {
userThreadList = await Client4.getUserThreads(userId, teamId, before, after, perPage, true, deleted, unread, since);
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
if (userThreadList) {
const data = {
threads: [] as UserThread[],
participants: [] as UserThread['participants'],
participantIds: [] as string[],
posts: [] as Post[],
};
userThreadList.threads?.forEach((thread) => {
// threads
data.threads.push({
...thread,
is_following: true,
});
// participants, participantIds
thread.participants?.forEach((participant) => {
data.participantIds.push(participant.id);
data.participants.push(participant);
});
// posts
data.posts.push({
...thread.post,
participants: thread.participants,
});
});
const getThreadsActions: Array<GenericAction> = [
{
type: ThreadTypes.RECEIVED_THREADS,
data: {
...userThreadList,
threads: data.threads,
team_id: teamId,
},
},
];
if (userThreadList.threads?.length) {
const flat = require('array.prototype.flat');
dispatch(
getMissingProfilesByIds(Array.from(
new Set(
flat(data.participantIds) as string[],
),
)),
);
getThreadsActions.push(
{
type: UserTypes.RECEIVED_PROFILES_LIST,
data: flat(data.participants),
},
{
type: PostTypes.RECEIVED_POSTS,
data: {posts: data.posts},
},
);
}
dispatch(batchActions(getThreadsActions));
}
return {data: userThreadList};
};
}
export function getThread(userId: string, teamId: string, threadId: string, extended = false) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
let thread;
try {
thread = await Client4.getUserThread(userId, teamId, threadId, extended);
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
if (thread) {
const {data} = dispatch(handleThreadArrived(thread, teamId)) as ActionResult;
thread = data;
}
return {data: thread};
};
}
export function handleThreadArrived(threadData: UserThread, teamId: string) {
return (dispatch: DispatchFunc, getState: GetStateFunc) => {
const thread = {...threadData, is_following: true};
const state = getState();
const currentUserId = getCurrentUserId(state);
const currentTeamId = getCurrentTeamId(state);
dispatch(batchActions([
{
type: UserTypes.RECEIVED_PROFILES_LIST,
data: thread.participants?.filter((user) => user.id !== currentUserId),
},
{
type: PostTypes.RECEIVED_POSTS,
data: {posts: [{...thread.post, participants: thread.participants}]},
},
{
type: ThreadTypes.RECEIVED_THREAD,
data: {
thread,
team_id: teamId,
},
},
]));
const oldThreadData = getThreadSelector(state, threadData.id);
dispatch(handleReadChanged(
thread.id,
teamId || currentTeamId,
thread.post.channel_id,
{
lastViewedAt: thread.last_viewed_at,
prevUnreadMentions: oldThreadData?.unread_mentions ?? 0,
newUnreadMentions: thread.unread_mentions,
prevUnreadReplies: oldThreadData?.unread_replies ?? 0,
newUnreadReplies: thread.unread_replies,
},
));
return {data: thread};
};
}
export function handleAllMarkedRead(teamId: string) {
return (dispatch: DispatchFunc) => {
dispatch({
type: ThreadTypes.ALL_TEAM_THREADS_READ,
data: {
team_id: teamId,
},
});
return {data: true};
};
}
export function markAllThreadsInTeamRead(userId: string, teamId: string) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
try {
await Client4.updateThreadsReadForUser(userId, teamId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
dispatch(handleAllMarkedRead(teamId));
return {data: true};
};
}
export function updateThreadRead(userId: string, threadId: string, timestamp: number) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
const teamId = getThreadTeamId(getState(), threadId);
try {
await Client4.updateThreadReadForUser(userId, teamId, threadId, timestamp);
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
return {};
};
}
export function handleFollowChanged(threadId: string, teamId: string, following: boolean) {
return (dispatch: DispatchFunc) => {
dispatch({
type: ThreadTypes.FOLLOW_CHANGED_THREAD,
data: {
id: threadId,
team_id: teamId,
following,
},
});
return {data: true};
};
}
export function setThreadFollow(userId: string, threadId: string, newState: boolean) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
const teamId = getThreadTeamId(getState(), threadId);
try {
await Client4.updateThreadFollowForUser(userId, teamId, threadId, newState);
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
dispatch({
type: ThreadTypes.FOLLOW_CHANGED_THREAD,
data: {
id: threadId,
team_id: teamId,
following: newState,
},
});
return {data: true};
};
}
export function handleReadChanged(
threadId: string,
teamId: string,
channelId: string,
{
lastViewedAt,
prevUnreadMentions,
newUnreadMentions,
prevUnreadReplies,
newUnreadReplies,
}: {
lastViewedAt: number;
prevUnreadMentions: number;
newUnreadMentions: number;
prevUnreadReplies: number;
newUnreadReplies: number;
},
) {
return (dispatch: DispatchFunc) => {
dispatch({
type: ThreadTypes.READ_CHANGED_THREAD,
data: {
id: threadId,
teamId,
channelId,
lastViewedAt,
prevUnreadMentions,
newUnreadMentions,
prevUnreadReplies,
newUnreadReplies,
},
});
return {data: true};
};
}