From a83f40b41a3946048b76df0cef94d7ea72d78003 Mon Sep 17 00:00:00 2001 From: Avinash Lingaloo Date: Thu, 17 Feb 2022 17:43:59 +0400 Subject: [PATCH] MM-41889 Gekidou Post Options menu - save/unsave option (#5980) * Added save/unsave option * code clean up * code correction * removed await --- app/actions/remote/preference.ts | 90 +++++++++++++++++-- app/client/rest/preferences.ts | 2 + .../post_options/options/save_option.tsx | 24 ++--- app/screens/post_options/post_options.tsx | 6 +- 4 files changed, 102 insertions(+), 20 deletions(-) diff --git a/app/actions/remote/preference.ts b/app/actions/remote/preference.ts index 6b08e85ce..55fa4c5c3 100644 --- a/app/actions/remote/preference.ts +++ b/app/actions/remote/preference.ts @@ -4,14 +4,17 @@ import {Preferences} from '@constants'; import DatabaseManager from '@database/manager'; import NetworkManager from '@init/network_manager'; +import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; import {queryCurrentUserId} from '@queries/servers/system'; import {forceLogoutIfNecessary} from './session'; +const {CATEGORY_FAVORITE_CHANNEL, CATEGORY_SAVED_POST} = Preferences; + export type MyPreferencesRequest = { preferences?: PreferenceType[]; error?: unknown; -} +}; export const fetchMyPreferences = async (serverUrl: string, fetchOnly = false): Promise => { let client; @@ -48,6 +51,47 @@ export const saveFavoriteChannel = async (serverUrl: string, channelId: string, return {error: `${serverUrl} database not found`}; } + try { + // Todo: @shaz I think you'll need to add the category handler here so that the channel is added/removed from the favorites category + const userId = await queryCurrentUserId(operator.database); + const favPref: PreferenceType = { + category: CATEGORY_FAVORITE_CHANNEL, + name: channelId, + user_id: userId, + value: String(isFavorite), + }; + return savePreference(serverUrl, [favPref]); + } catch (error) { + return {error}; + } +}; + +export const savePostPreference = async (serverUrl: string, postId: string) => { + const operator = DatabaseManager.serverDatabases[serverUrl]?.operator; + if (!operator) { + return {error: `${serverUrl} database not found`}; + } + + try { + const userId = await queryCurrentUserId(operator.database); + const pref: PreferenceType = { + user_id: userId, + category: CATEGORY_SAVED_POST, + name: postId, + value: 'true', + }; + return savePreference(serverUrl, [pref]); + } catch (error) { + return {error}; + } +}; + +export const savePreference = async (serverUrl: string, preferences: PreferenceType[]) => { + const operator = DatabaseManager.serverDatabases[serverUrl]?.operator; + if (!operator) { + return {error: `${serverUrl} database not found`}; + } + let client; try { client = NetworkManager.getClient(serverUrl); @@ -56,15 +100,7 @@ export const saveFavoriteChannel = async (serverUrl: string, channelId: string, } try { - // Todo: @shaz I think you'll need to add the category handler here so that the channel is added/removed from the favorites category const userId = await queryCurrentUserId(operator.database); - const favPref: PreferenceType = { - category: Preferences.CATEGORY_FAVORITE_CHANNEL, - name: channelId, - user_id: userId, - value: String(isFavorite), - }; - const preferences = [favPref]; client.savePreferences(userId, preferences); await operator.handlePreferences({ preferences, @@ -77,3 +113,39 @@ export const saveFavoriteChannel = async (serverUrl: string, channelId: string, return {error}; } }; + +export const deleteSavedPost = async (serverUrl: string, postId: string) => { + const operator = DatabaseManager.serverDatabases[serverUrl]?.operator; + if (!operator) { + return {error: `${serverUrl} database not found`}; + } + let client; + try { + client = NetworkManager.getClient(serverUrl); + } catch (error) { + return {error}; + } + try { + const userId = await queryCurrentUserId(operator.database); + const records = await queryPreferencesByCategoryAndName(operator.database, CATEGORY_SAVED_POST, postId); + const postPreferenceRecord = records.find((r) => postId === r.name); + const pref = { + user_id: userId, + category: CATEGORY_SAVED_POST, + name: postId, + value: 'true', + }; + + if (postPreferenceRecord) { + client.deletePreferences(userId, [pref]); + await postPreferenceRecord.destroyPermanently(); + } + + return { + preference: pref, + }; + } catch (error) { + forceLogoutIfNecessary(serverUrl, error as ClientErrorProps); + return {error}; + } +}; diff --git a/app/client/rest/preferences.ts b/app/client/rest/preferences.ts index aa5a0e21d..db69d414b 100644 --- a/app/client/rest/preferences.ts +++ b/app/client/rest/preferences.ts @@ -9,6 +9,7 @@ export interface ClientPreferencesMix { const ClientPreferences = (superclass: any) => class extends superclass { savePreferences = async (userId: string, preferences: PreferenceType[]) => { + this.analytics.trackAPI('action_posts_flag'); return this.doFetch( `${this.getPreferencesRoute(userId)}`, {method: 'put', body: preferences}, @@ -23,6 +24,7 @@ const ClientPreferences = (superclass: any) => class extends superclass { }; deletePreferences = async (userId: string, preferences: PreferenceType[]) => { + this.analytics.trackAPI('action_posts_unflag'); return this.doFetch( `${this.getPreferencesRoute(userId)}/delete`, {method: 'post', body: preferences}, diff --git a/app/screens/post_options/options/save_option.tsx b/app/screens/post_options/options/save_option.tsx index b60baa61e..954e4eb1f 100644 --- a/app/screens/post_options/options/save_option.tsx +++ b/app/screens/post_options/options/save_option.tsx @@ -1,35 +1,39 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {useCallback} from 'react'; +import {deleteSavedPost, savePostPreference} from '@actions/remote/preference'; +import {Screens} from '@constants'; +import {useServerUrl} from '@context/server'; import {t} from '@i18n'; +import {dismissBottomSheet} from '@screens/navigation'; import BaseOption from './base_option'; type CopyTextProps = { isSaved: boolean; + postId: string; } -const SaveOption = ({isSaved}: CopyTextProps) => { - const handleUnsavePost = () => { - //todo: - }; +const SaveOption = ({isSaved, postId}: CopyTextProps) => { + const serverUrl = useServerUrl(); - const handleSavePost = () => { - //todo: - }; + const onHandlePress = useCallback(async () => { + const remoteAction = isSaved ? deleteSavedPost : savePostPreference; + remoteAction(serverUrl, postId); + dismissBottomSheet(Screens.POST_OPTIONS); + }, [postId, serverUrl]); const id = isSaved ? t('mobile.post_info.unsave') : t('mobile.post_info.save'); const defaultMessage = isSaved ? 'Unsave' : 'Save'; - const onPress = isSaved ? handleUnsavePost : handleSavePost; return ( ); diff --git a/app/screens/post_options/post_options.tsx b/app/screens/post_options/post_options.tsx index 1e3deaf82..af6363256 100644 --- a/app/screens/post_options/post_options.tsx +++ b/app/screens/post_options/post_options.tsx @@ -76,7 +76,11 @@ const PostOptions = ({ } {canMarkAsUnread && !isSystemPost && ()} {canCopyPermalink && } - {!isSystemPost && } + {!isSystemPost && + } {canCopyText && } {canPin && } {canEdit && }