// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import {buildQueryString} from '@utils/helpers'; import {PER_PAGE_DEFAULT} from './constants'; import type ClientBase from './base'; export interface ClientPostsMix { createPost: (post: Post) => Promise; updatePost: (post: Post) => Promise; getPost: (postId: string) => Promise; patchPost: (postPatch: Partial & {id: string}) => Promise; deletePost: (postId: string) => Promise; getPostThread: (postId: string, options: FetchPaginatedThreadOptions) => Promise; getPosts: (channelId: string, page?: number, perPage?: number, collapsedThreads?: boolean, collapsedThreadsExtended?: boolean) => Promise; getPostsSince: (channelId: string, since: number, collapsedThreads?: boolean, collapsedThreadsExtended?: boolean) => Promise; getPostsBefore: (channelId: string, postId?: string, page?: number, perPage?: number, collapsedThreads?: boolean, collapsedThreadsExtended?: boolean) => Promise; getPostsAfter: (channelId: string, postId: string, page?: number, perPage?: number, collapsedThreads?: boolean, collapsedThreadsExtended?: boolean) => Promise; getFileInfosForPost: (postId: string) => Promise; getSavedPosts: (userId: string, channelId?: string, teamId?: string, page?: number, perPage?: number) => Promise; getPinnedPosts: (channelId: string) => Promise; markPostAsUnread: (userId: string, postId: string) => Promise; pinPost: (postId: string) => Promise; unpinPost: (postId: string) => Promise; addReaction: (userId: string, postId: string, emojiName: string) => Promise; removeReaction: (userId: string, postId: string, emojiName: string) => Promise; getReactionsForPost: (postId: string) => Promise; searchPostsWithParams: (teamId: string, params: PostSearchParams) => Promise; searchPosts: (teamId: string, terms: string, isOrSearch: boolean) => Promise; doPostAction: (postId: string, actionId: string, selectedOption?: string) => Promise; doPostActionWithCookie: (postId: string, actionId: string, actionCookie: string, selectedOption?: string) => Promise; acknowledgePost: (postId: string, userId: string) => Promise; unacknowledgePost: (postId: string, userId: string) => Promise; } const ClientPosts = >(superclass: TBase) => class extends superclass { createPost = async (post: Post) => { return this.doFetch( `${this.getPostsRoute()}`, {method: 'post', body: post, noRetry: true}, ); }; updatePost = async (post: Post) => { return this.doFetch( `${this.getPostRoute(post.id)}`, {method: 'put', body: post}, ); }; getPost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}`, {method: 'get'}, ); }; patchPost = async (postPatch: Partial & {id: string}) => { return this.doFetch( `${this.getPostRoute(postPatch.id)}/patch`, {method: 'put', body: postPatch}, ); }; deletePost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}`, {method: 'delete'}, ); }; getPostThread = (postId: string, options: FetchPaginatedThreadOptions) => { const { fetchThreads = true, collapsedThreads = false, collapsedThreadsExtended = false, direction = 'up', fetchAll = false, perPage = fetchAll ? undefined : PER_PAGE_DEFAULT, ...rest } = options; return this.doFetch( `${this.getPostRoute(postId)}/thread${buildQueryString({skipFetchThreads: !fetchThreads, collapsedThreads, collapsedThreadsExtended, direction, perPage, ...rest})}`, {method: 'get'}, ); }; getPosts = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT, collapsedThreads = false, collapsedThreadsExtended = false) => { return this.doFetch( `${this.getChannelRoute(channelId)}/posts${buildQueryString({page, per_page: perPage, collapsedThreads, collapsedThreadsExtended})}`, {method: 'get'}, ); }; getPostsSince = async (channelId: string, since: number, collapsedThreads = false, collapsedThreadsExtended = false) => { return this.doFetch( `${this.getChannelRoute(channelId)}/posts${buildQueryString({since, collapsedThreads, collapsedThreadsExtended})}`, {method: 'get'}, ); }; getPostsBefore = async (channelId: string, postId = '', page = 0, perPage = PER_PAGE_DEFAULT, collapsedThreads = false, collapsedThreadsExtended = false) => { return this.doFetch( `${this.getChannelRoute(channelId)}/posts${buildQueryString({before: postId, page, per_page: perPage, collapsedThreads, collapsedThreadsExtended})}`, {method: 'get'}, ); }; getPostsAfter = async (channelId: string, postId: string, page = 0, perPage = PER_PAGE_DEFAULT, collapsedThreads = false, collapsedThreadsExtended = false) => { return this.doFetch( `${this.getChannelRoute(channelId)}/posts${buildQueryString({after: postId, page, per_page: perPage, collapsedThreads, collapsedThreadsExtended})}`, {method: 'get'}, ); }; getFileInfosForPost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}/files/info`, {method: 'get'}, ); }; getSavedPosts = async (userId: string, channelId = '', teamId = '', page = 0, perPage = PER_PAGE_DEFAULT) => { return this.doFetch( `${this.getUserRoute(userId)}/posts/flagged${buildQueryString({channel_id: channelId, team_id: teamId, page, per_page: perPage})}`, {method: 'get'}, ); }; getPinnedPosts = async (channelId: string) => { return this.doFetch( `${this.getChannelRoute(channelId)}/pinned`, {method: 'get'}, ); }; markPostAsUnread = async (userId: string, postId: string) => { // collapsed_threads_supported is not based on user preferences but to know if "CLIENT" supports CRT const body = JSON.stringify({collapsed_threads_supported: true}); return this.doFetch( `${this.getUserRoute(userId)}/posts/${postId}/set_unread`, {method: 'post', body}, ); }; pinPost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}/pin`, {method: 'post'}, ); }; unpinPost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}/unpin`, {method: 'post'}, ); }; addReaction = async (userId: string, postId: string, emojiName: string) => { return this.doFetch( `${this.getReactionsRoute()}`, {method: 'post', body: {user_id: userId, post_id: postId, emoji_name: emojiName}}, ); }; removeReaction = async (userId: string, postId: string, emojiName: string) => { return this.doFetch( `${this.getUserRoute(userId)}/posts/${postId}/reactions/${emojiName}`, {method: 'delete'}, ); }; getReactionsForPost = async (postId: string) => { return this.doFetch( `${this.getPostRoute(postId)}/reactions`, {method: 'get'}, ); }; searchPostsWithParams = async (teamId: string, params: PostSearchParams) => { const endpoint = teamId ? `${this.getTeamRoute(teamId)}/posts/search` : `${this.getPostsRoute()}/search`; return this.doFetch(endpoint, {method: 'post', body: params}); }; searchPosts = async (teamId: string, terms: string, isOrSearch: boolean) => { return this.searchPostsWithParams(teamId, {terms, is_or_search: isOrSearch}); }; doPostAction = async (postId: string, actionId: string, selectedOption = '') => { return this.doPostActionWithCookie(postId, actionId, '', selectedOption); }; doPostActionWithCookie = async (postId: string, actionId: string, actionCookie: string, selectedOption = '') => { const msg: any = { selected_option: selectedOption, }; if (actionCookie !== '') { msg.cookie = actionCookie; } return this.doFetch( `${this.getPostRoute(postId)}/actions/${encodeURIComponent(actionId)}`, {method: 'post', body: msg}, ); }; acknowledgePost = async (postId: string, userId: string) => { return this.doFetch( `${this.getUserRoute(userId)}/posts/${postId}/ack`, {method: 'post'}, ); }; unacknowledgePost = async (postId: string, userId: string) => { return this.doFetch( `${this.getUserRoute(userId)}/posts/${postId}/ack`, {method: 'delete'}, ); }; }; export default ClientPosts;