forked from Ivasoft/mattermost-mobile
* MM-39710: saved posts screen and DB - Adds ids of saved posts to the systems table, as we do with recent mentions. - Adds a new remote action to fetch saved posts (getFlaggedPosts). - Adds a new screen to display those in a mobile. - Displays saved posts in the tablet view next to profile card. * Uses Preferences instead of System table Renames to saved posts wherever possible * Adds text to localization file * Fixes fetching/saving saved posts * Refactor mini post to components folder * Fixes hooks dependencies according to review * Removes unnecessary 'withObservables' * Small refactor * Satisfies linter * Adds empty state And fixes empty state icon to be theme sensitive. Both recent_mentions and saved_posts. * Fixes empty screen's alignment * Add missing preference * add missing translation strings * remove unused database type definition * Fetch newly saved post * Fix return type for client.getSavedPosts * Remove usage of lodash compose * Rename get remote actions to fetch * Include close button for savedPost modal * fix tablet view for SavePosts and use lottie loading indicator * Render post with content for save posts and recent mentions * post list viewable items type definition * Add layout width to post content for saved post screen * Use PostWithChannel and viewableItems for saved posts and recent mentions * Layout margin of 20 * openGraphImage margin * Fix openGraphImage display Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
232 lines
8.5 KiB
TypeScript
232 lines
8.5 KiB
TypeScript
// 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';
|
|
|
|
export interface ClientPostsMix {
|
|
createPost: (post: Post) => Promise<Post>;
|
|
updatePost: (post: Post) => Promise<Post>;
|
|
getPost: (postId: string) => Promise<Post>;
|
|
patchPost: (postPatch: Partial<Post> & {id: string}) => Promise<Post>;
|
|
deletePost: (postId: string) => Promise<any>;
|
|
getPostThread: (postId: string) => Promise<any>;
|
|
getPosts: (channelId: string, page?: number, perPage?: number) => Promise<PostResponse>;
|
|
getPostsSince: (channelId: string, since: number) => Promise<PostResponse>;
|
|
getPostsBefore: (channelId: string, postId: string, page?: number, perPage?: number) => Promise<PostResponse>;
|
|
getPostsAfter: (channelId: string, postId: string, page?: number, perPage?: number) => Promise<PostResponse>;
|
|
getFileInfosForPost: (postId: string) => Promise<FileInfo[]>;
|
|
getSavedPosts: (userId: string, channelId?: string, teamId?: string, page?: number, perPage?: number) => Promise<PostResponse>;
|
|
getPinnedPosts: (channelId: string) => Promise<any>;
|
|
markPostAsUnread: (userId: string, postId: string) => Promise<any>;
|
|
pinPost: (postId: string) => Promise<any>;
|
|
unpinPost: (postId: string) => Promise<any>;
|
|
addReaction: (userId: string, postId: string, emojiName: string) => Promise<Reaction>;
|
|
removeReaction: (userId: string, postId: string, emojiName: string) => Promise<any>;
|
|
getReactionsForPost: (postId: string) => Promise<any>;
|
|
searchPostsWithParams: (teamId: string, params: PostSearchParams) => Promise<any>;
|
|
searchPosts: (teamId: string, terms: string, isOrSearch: boolean) => Promise<any>;
|
|
doPostAction: (postId: string, actionId: string, selectedOption?: string) => Promise<any>;
|
|
doPostActionWithCookie: (postId: string, actionId: string, actionCookie: string, selectedOption?: string) => Promise<any>;
|
|
}
|
|
|
|
const ClientPosts = (superclass: any) => class extends superclass {
|
|
createPost = async (post: Post) => {
|
|
this.analytics.trackAPI('api_posts_create', {channel_id: post.channel_id});
|
|
|
|
if (post.root_id != null && post.root_id !== '') {
|
|
this.analytics.trackAPI('api_posts_replied', {channel_id: post.channel_id});
|
|
}
|
|
|
|
return this.doFetch(
|
|
`${this.getPostsRoute()}`,
|
|
{method: 'post', body: post, noRetry: true},
|
|
);
|
|
};
|
|
|
|
updatePost = async (post: Post) => {
|
|
this.analytics.trackAPI('api_posts_update', {channel_id: post.channel_id});
|
|
|
|
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<Post> & {id: string}) => {
|
|
this.analytics.trackAPI('api_posts_patch', {channel_id: postPatch.channel_id});
|
|
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postPatch.id)}/patch`,
|
|
{method: 'put', body: postPatch},
|
|
);
|
|
};
|
|
|
|
deletePost = async (postId: string) => {
|
|
this.analytics.trackAPI('api_posts_delete');
|
|
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postId)}`,
|
|
{method: 'delete'},
|
|
);
|
|
};
|
|
|
|
getPostThread = async (postId: string) => {
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postId)}/thread`,
|
|
{method: 'get'},
|
|
);
|
|
};
|
|
|
|
getPosts = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
|
return this.doFetch(
|
|
`${this.getChannelRoute(channelId)}/posts${buildQueryString({page, per_page: perPage})}`,
|
|
{method: 'get'},
|
|
);
|
|
};
|
|
|
|
getPostsSince = async (channelId: string, since: number) => {
|
|
return this.doFetch(
|
|
`${this.getChannelRoute(channelId)}/posts${buildQueryString({since})}`,
|
|
{method: 'get'},
|
|
);
|
|
};
|
|
|
|
getPostsBefore = async (channelId: string, postId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
|
this.analytics.trackAPI('api_posts_get_before', {channel_id: channelId});
|
|
|
|
return this.doFetch(
|
|
`${this.getChannelRoute(channelId)}/posts${buildQueryString({before: postId, page, per_page: perPage})}`,
|
|
{method: 'get'},
|
|
);
|
|
};
|
|
|
|
getPostsAfter = async (channelId: string, postId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
|
this.analytics.trackAPI('api_posts_get_after', {channel_id: channelId});
|
|
|
|
return this.doFetch(
|
|
`${this.getChannelRoute(channelId)}/posts${buildQueryString({after: postId, page, per_page: perPage})}`,
|
|
{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) => {
|
|
this.analytics.trackAPI('api_posts_get_flagged', {team_id: teamId});
|
|
|
|
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) => {
|
|
this.analytics.trackAPI('api_posts_get_pinned', {channel_id: channelId});
|
|
return this.doFetch(
|
|
`${this.getChannelRoute(channelId)}/pinned`,
|
|
{method: 'get'},
|
|
);
|
|
};
|
|
|
|
markPostAsUnread = async (userId: string, postId: string) => {
|
|
this.analytics.trackAPI('api_post_set_unread_post');
|
|
|
|
return this.doFetch(
|
|
`${this.getUserRoute(userId)}/posts/${postId}/set_unread`,
|
|
{method: 'post'},
|
|
);
|
|
};
|
|
|
|
pinPost = async (postId: string) => {
|
|
this.analytics.trackAPI('api_posts_pin');
|
|
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postId)}/pin`,
|
|
{method: 'post'},
|
|
);
|
|
};
|
|
|
|
unpinPost = async (postId: string) => {
|
|
this.analytics.trackAPI('api_posts_unpin');
|
|
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postId)}/unpin`,
|
|
{method: 'post'},
|
|
);
|
|
};
|
|
|
|
addReaction = async (userId: string, postId: string, emojiName: string) => {
|
|
this.analytics.trackAPI('api_reactions_save', {post_id: postId});
|
|
|
|
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) => {
|
|
this.analytics.trackAPI('api_reactions_delete', {post_id: postId});
|
|
|
|
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) => {
|
|
this.analytics.trackAPI('api_posts_search');
|
|
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 = '') => {
|
|
if (selectedOption) {
|
|
this.analytics.trackAPI('api_interactive_messages_menu_selected');
|
|
} else {
|
|
this.analytics.trackAPI('api_interactive_messages_button_clicked');
|
|
}
|
|
|
|
const msg: any = {
|
|
selected_option: selectedOption,
|
|
};
|
|
if (actionCookie !== '') {
|
|
msg.cookie = actionCookie;
|
|
}
|
|
return this.doFetch(
|
|
`${this.getPostRoute(postId)}/actions/${encodeURIComponent(actionId)}`,
|
|
{method: 'post', body: msg},
|
|
);
|
|
};
|
|
};
|
|
|
|
export default ClientPosts;
|