* WS Events, Actions, Queries, Thread Follow, Post Query * i18n changes * Misc * Only unread threads are marked as read * Mark threads from WS even as visible in Global threads * Merge fixes * Update thread_post_list.tsx * Merge fix * Feedback fix * Make teamId in handleThreads optional for unfollowed threads * Removed unwated type and return * Review changes * Removing unused model * Merge fix * Misc fixes * Following button query change
196 lines
5.5 KiB
TypeScript
196 lines
5.5 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import {markTeamThreadsAsRead, processReceivedThreads, switchToThread, updateThread} from '@actions/local/thread';
|
|
import {fetchPostThread} from '@actions/remote/post';
|
|
import {General} from '@constants';
|
|
import DatabaseManager from '@database/manager';
|
|
import NetworkManager from '@init/network_manager';
|
|
import {getChannelById} from '@queries/servers/channel';
|
|
import {getPostById} from '@queries/servers/post';
|
|
import {getCommonSystemValues} from '@queries/servers/system';
|
|
import {getIsCRTEnabled, getThreadById} from '@queries/servers/thread';
|
|
|
|
import {forceLogoutIfNecessary} from './session';
|
|
|
|
type FetchThreadsRequest = {
|
|
error?: unknown;
|
|
} | {
|
|
data: GetUserThreadsResponse;
|
|
};
|
|
|
|
type FetchThreadsOptions = {
|
|
before?: string;
|
|
after?: string;
|
|
perPage?: number;
|
|
deleted?: boolean;
|
|
unread?: boolean;
|
|
since?: number;
|
|
}
|
|
|
|
export const fetchAndSwitchToThread = async (serverUrl: string, rootId: string) => {
|
|
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
|
if (!database) {
|
|
return {error: `${serverUrl} database not found`};
|
|
}
|
|
|
|
// Load thread before we open to the thread modal
|
|
// @Todo: https://mattermost.atlassian.net/browse/MM-42232
|
|
fetchPostThread(serverUrl, rootId);
|
|
|
|
// Mark thread as read
|
|
const isCRTEnabled = await getIsCRTEnabled(database);
|
|
if (isCRTEnabled) {
|
|
const post = await getPostById(database, rootId);
|
|
if (post) {
|
|
const thread = await getThreadById(database, rootId);
|
|
if (thread?.unreadReplies || thread?.unreadMentions) {
|
|
const channel = await getChannelById(database, post.channelId);
|
|
if (channel) {
|
|
updateThreadRead(serverUrl, channel.teamId, thread.id, Date.now());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
switchToThread(serverUrl, rootId);
|
|
|
|
return {};
|
|
};
|
|
|
|
export const fetchThreads = async (
|
|
serverUrl: string,
|
|
teamId: string,
|
|
{
|
|
before,
|
|
after,
|
|
perPage = General.CRT_CHUNK_SIZE,
|
|
deleted = false,
|
|
unread = false,
|
|
since = 0,
|
|
}: FetchThreadsOptions = {
|
|
perPage: General.CRT_CHUNK_SIZE,
|
|
deleted: false,
|
|
unread: false,
|
|
since: 0,
|
|
},
|
|
): Promise<FetchThreadsRequest> => {
|
|
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
|
if (!database) {
|
|
return {error: `${serverUrl} database not found`};
|
|
}
|
|
|
|
let client;
|
|
try {
|
|
client = NetworkManager.getClient(serverUrl);
|
|
} catch (error) {
|
|
return {error};
|
|
}
|
|
|
|
try {
|
|
const {config} = await getCommonSystemValues(database);
|
|
|
|
const data = await client.getThreads('me', teamId, before, after, perPage, deleted, unread, since, config.Version);
|
|
|
|
const {threads} = data;
|
|
|
|
if (threads.length) {
|
|
// Mark all fetched threads as following
|
|
threads.forEach((thread: Thread) => {
|
|
thread.is_following = true;
|
|
});
|
|
|
|
await processReceivedThreads(serverUrl, threads, teamId);
|
|
}
|
|
|
|
return {data};
|
|
} catch (error) {
|
|
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
|
return {error};
|
|
}
|
|
};
|
|
|
|
export const fetchThread = async (serverUrl: string, teamId: string, threadId: string, extended?: boolean) => {
|
|
let client;
|
|
try {
|
|
client = NetworkManager.getClient(serverUrl);
|
|
} catch (error) {
|
|
return {error};
|
|
}
|
|
|
|
try {
|
|
const thread = await client.getThread('me', teamId, threadId, extended);
|
|
|
|
await processReceivedThreads(serverUrl, [thread], teamId);
|
|
|
|
return {data: thread};
|
|
} catch (error) {
|
|
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
|
return {error};
|
|
}
|
|
};
|
|
|
|
export const updateTeamThreadsAsRead = async (serverUrl: string, teamId: string) => {
|
|
let client;
|
|
try {
|
|
client = NetworkManager.getClient(serverUrl);
|
|
} catch (error) {
|
|
return {error};
|
|
}
|
|
|
|
try {
|
|
const data = await client.updateTeamThreadsAsRead('me', teamId);
|
|
|
|
// Update locally
|
|
await markTeamThreadsAsRead(serverUrl, teamId);
|
|
|
|
return {data};
|
|
} catch (error) {
|
|
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
|
return {error};
|
|
}
|
|
};
|
|
|
|
export const updateThreadRead = async (serverUrl: string, teamId: string, threadId: string, timestamp: number) => {
|
|
let client;
|
|
try {
|
|
client = NetworkManager.getClient(serverUrl);
|
|
} catch (error) {
|
|
return {error};
|
|
}
|
|
|
|
try {
|
|
const data = await client.updateThreadRead('me', teamId, threadId, timestamp);
|
|
|
|
// Update locally
|
|
await updateThread(serverUrl, threadId, {
|
|
last_viewed_at: timestamp,
|
|
});
|
|
|
|
return {data};
|
|
} catch (error) {
|
|
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
|
return {error};
|
|
}
|
|
};
|
|
|
|
export const updateThreadFollowing = async (serverUrl: string, teamId: string, threadId: string, state: boolean) => {
|
|
let client;
|
|
try {
|
|
client = NetworkManager.getClient(serverUrl);
|
|
} catch (error) {
|
|
return {error};
|
|
}
|
|
|
|
try {
|
|
const data = await client.updateThreadFollow('me', teamId, threadId, state);
|
|
|
|
// Update locally
|
|
await updateThread(serverUrl, threadId, {is_following: state});
|
|
|
|
return {data};
|
|
} catch (error) {
|
|
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
|
return {error};
|
|
}
|
|
};
|