Source: app/actions/resources/communityActions.js

import imageInputRESTFormatter from '../../util/imageInputRESTFormatter';
import PostType from '../../data/enum/PostType';
import SortType from '../../data/enum/SortType';
import { convertBitwiseToArray } from '../../util/bitwiseUtils';
import GatewayError from '../../net/gateway/GatewayError';
import isAdministratorOrModerator from '../../util/userRoleUtil';
import { userIdSelector } from '../../selectors/userAccountSelectors';
import {
  GATEWAY_COMMUNITY_AUTH,
  GATEWAY_COMMUNITY_V2_AUTH,
  GATEWAY_CONTENT_AUTH,
} from '../../data/Injectables';
import { COMMENT, POST, TAG, COMMUNITY_GROUP } from '../../data/entityTypes';
import dedupeAsyncThunk from '../../util/dedupeAsyncThunk';
import { removeEntities, setEntity } from '../entities/entityActions';
import { apiDelete, apiPatch, apiPost, apiGet } from './apiActions/apiRequest';
import getDefaultApiEntityTransform from './apiActions/getDefaultApiEntityTransform';
import apiGetEntity from './apiActions/apiGetEntity';
import apiGetCollection, {
  collectionCachingNoPagination,
  addEntitiesFromApiData,
  GET_NEXT,
} from './apiActions/apiGetCollection';
import {
  groupPostsCollectionId,
  communityCommentsCollectionId,
  communityPostsCollectionId,
  communityRelatedPostsCollectionId,
  communityGroupPostsCollectionId,
  COMMUNITY_TAGS,
  COMMUNITY_GROUPS,
  COMMUNITY_MEMBER_GROUPS,
} from '../../data/collectionIds';
import { POST_OVERVIEW, COMMUNITY_GROUP_POSTS } from '../../data/collectionPaginationViews';
import {
  collectionClearAll,
  collectionClearIfContainsRef,
  collectionPartitionCheckComplete,
  collectionRemoveRefs,
} from '../entities/collectionActions';
import getGroupId from '../../util/getGroupId';
import authenticate from '../../util/auth/authenticate';
import { getUserPermissionStoredData } from '../../util/userPermissionStateUtil';

export const GET_COMMUNITY_FEED = 'communityActions/GET_COMMUNITY_FEED';

export const getCommunityFeed = (
  {
    sort,
    includePinnedFirst = false,
    loadMore = true,
    includeLastLike = true,
    limit = 10,
    useCursorPagination = true,
  },
  getFresh = false,
) => async (dispatch, getState) => {
  const { requestData, requestPagination } = buildPostFilters({
    sort,
    includePinnedFirst,
    loadMore,
    includeLastLike,
    limit,
    useCursorPagination,
  });

  await authenticate();
  const userId = userIdSelector(getState());

  return dispatch(
    apiGetCollection(
      GET_COMMUNITY_FEED,
      GATEWAY_COMMUNITY_AUTH,
      `/profiles/${userId}/community-feed`,
      communityPostsCollectionId({ sort }),
      requestPagination,
      {
        updatePaginationView: {
          target: POST_OVERVIEW,
          extend: true,
        },
        requestData,
        entityType: POST,
        caching: getFresh ? false : undefined,
        transformResponse: response => {
          // eslint-disable-next-line no-unused-vars
          const { total: removeTotal, ...paginationWithoutTotal } = response.pagination;

          return {
            ...response,
            pagination: {
              ...paginationWithoutTotal,
            },
          };
        },
        transformEntity: transformNormalizePost,
      },
    ),
  ).then(({ result }) => {
    dispatch(
      addCommunityGroupEntitiesFromPosts(
        result.data,
        getDefaultApiEntityTransform(`/profiles/${userId}/community-feed`, GET_COMMUNITY_FEED),
      ),
    );
  });
};

export const GET_POSTS_OVERVIEW = 'communityActions/GET_POSTS_OVERVIEW';

export const getPostsOverview = (
  {
    tags = 0,
    onlyMe,
    sort,
    postType,
    isDeleted = false,
    includePinnedFirst = false,
    loadMore = true,
    includeTrending,
    includeLastLike = true,
    limit = 10,
    useCursorPagination = true,
  },
  containerId = null,
  getFresh = false,
) => dispatch => {
  const { requestData, requestPagination } = buildPostFilters({
    tags,
    onlyMe,
    sort,
    postType,
    isDeleted,
    includePinnedFirst,
    loadMore,
    includeTrending,
    includeLastLike,
    limit,
    useCursorPagination,
    containerId,
  });

  return dispatch(
    apiGetCollection(
      GET_POSTS_OVERVIEW,
      GATEWAY_COMMUNITY_V2_AUTH,
      '/posts',
      communityPostsCollectionId({ tags, onlyCurrentUser: onlyMe, postType, containerId, sort }),
      requestPagination,
      {
        updatePaginationView: {
          target: POST_OVERVIEW,
          extend: true,
        },
        requestData,
        entityType: POST,
        caching: getFresh ? false : undefined,
        transformResponse: response => {
          // eslint-disable-next-line no-unused-vars
          const { total: removeTotal, ...paginationWithoutTotal } = response.pagination;

          return {
            ...response,
            pagination: {
              ...paginationWithoutTotal,
            },
          };
        },
        transformEntity: transformNormalizePost,
      },
    ),
  ).then(({ result }) => {
    dispatch(
      addCommunityGroupEntitiesFromPosts(
        result.data,
        getDefaultApiEntityTransform(`/posts`, GET_POSTS_OVERVIEW),
      ),
    );
  });
};

export const GET_POST_DETAIL = 'communityActions/GET_POST_DETAIL';
/**
 * Gets a single post entity from the API
 * @param id {string} The ID of the post to get
 */
export const getPostDetail = id => dispatch =>
  dispatch(
    apiGetEntity(GET_POST_DETAIL, GATEWAY_COMMUNITY_V2_AUTH, `/posts/${id}`, POST, id, {
      updateEntityView: 'view.pages.communityDetail.post',
      requestData: {
        includeLastLike: true,
      },
      caching: false,
      transformEntity: transformNormalizePost,
    }),
  ).then(response => {
    if (response.entity.communityGroup) {
      dispatch(
        addEntitiesFromApiData(
          [response.entity.communityGroup],
          COMMUNITY_GROUP,
          undefined,
          getDefaultApiEntityTransform(`/posts/${id}`, GET_POST_DETAIL),
        ),
      );
    }

    return response;
  });

export const GET_RELATED_POSTS = 'communityActions/GET_RELATED_POSTS';

export const getRelatedPosts = postId => dispatch =>
  dispatch(
    apiGetCollection(
      GET_RELATED_POSTS,
      GATEWAY_COMMUNITY_AUTH,
      `/posts/${postId}/related`,
      communityRelatedPostsCollectionId({ postId }),
      {
        limit: 4,
        offset: 0,
      },
      {
        entityType: POST,
        transformEntity: transformNormalizePost,
      },
    ),
  ).then(({ result }) => {
    dispatch(
      addCommunityGroupEntitiesFromPosts(
        result.data,
        getDefaultApiEntityTransform(`/posts/${postId}/related`, GET_RELATED_POSTS),
      ),
    );
  });

export const GET_GROUP_POSTS = 'communityActions/GET_GROUP_POSTS';

export const getGroupPosts = (containerId = null, limit = 6) => async (dispatch, getState) => {
  // eslint-disable-next-line no-param-reassign
  containerId = await getGroupId(containerId, getState);
  return dispatch(
    apiGetCollection(
      GET_GROUP_POSTS,
      GATEWAY_COMMUNITY_AUTH,
      '/posts',
      groupPostsCollectionId({ containerId }),
      {
        limit,
      },
      {
        useCache: true,
        entityType: POST,
        requestData: {
          postType: PostType.POST,
          sort: SortType.NEWEST,
          containerId,
        },
      },
    ),
  );
};

export const GET_DISCUSSION_COMMENTS = 'communityActions/GET_DISCUSSION_COMMENTS';

export const getDiscussionComments = (id, isComment = false, loadMore = false) =>
  apiGetCollection(
    GET_DISCUSSION_COMMENTS,
    GATEWAY_COMMUNITY_V2_AUTH,
    '/comments',
    communityCommentsCollectionId({ parentId: id, parentIsComment: isComment }),
    {
      limit: 10,
      offset: loadMore ? GET_NEXT : 0,
    },
    {
      requestData: {
        [isComment ? 'parentId' : 'discussionId']: id,
        sort: isComment ? SortType.OLDEST : SortType.NEWEST,
      },
      entityType: COMMENT,
    },
  );

export const getDiscussionCommentsForDeeplink = (
  id,
  isComment = false,
  deeplink,
  { next = false, previous = false } = {},
) => (dispatch, getState) => {
  const collectionId = communityCommentsCollectionId({
    parentId: id,
    parentIsComment: isComment,
    deeplink: true,
  });
  let paginationOptions = isComment
    ? { from: { param: 'sinceId', value: deeplink, key: 'id' } }
    : { until: { param: 'untilId', value: deeplink, key: 'id' } };
  if (next) {
    if (previous) {
      throw new Error(
        'The next and previous options of getDiscussionCommentsForDeeplink are mutually exclusive',
      );
    }
    paginationOptions = { from: { param: 'sinceId', key: 'id' } };
  } else if (previous) {
    paginationOptions = { until: { param: 'untilId', key: 'id' } };
  }

  return dispatch(
    apiGetCollection(
      GET_DISCUSSION_COMMENTS,
      GATEWAY_COMMUNITY_V2_AUTH,
      '/comments',
      collectionId,
      {
        ...paginationOptions,
        limit: 10,
      },
      {
        requestData: {
          [isComment ? 'parentId' : 'discussionId']: id,
          sort: isComment ? SortType.OLDEST : SortType.NEWEST,
        },
        entityType: COMMENT,
      },
    ),
  ).then(result => {
    const { entities } = getState();

    if (!next && !previous) {
      const discussionEntityType = isComment ? 'comment' : 'post';
      const discussionTotalProp = isComment ? 'repliesCount' : 'commentsCount';

      const total = entities[discussionEntityType]?.[id]?.[discussionTotalProp];

      if (typeof total === 'number') {
        dispatch(collectionPartitionCheckComplete(collectionId, total));
      }
    }

    return result;
  });
};

export const GET_COMMUNITY_TAGS = 'communityActions/GET_COMMUNITY_TAGS';

export const getCommunityTags = dedupeAsyncThunk(() => async (dispatch, getState) => {
  await authenticate();
  const adminOrModerator = isAdministratorOrModerator(
    getUserPermissionStoredData({ getState }).roles,
  );

  return dispatch(
    apiGetCollection(
      GET_COMMUNITY_TAGS,
      GATEWAY_CONTENT_AUTH,
      '/community-post-tags',
      COMMUNITY_TAGS,
      {},
      {
        entityType: TAG,
        // simplified caching. If we have any tags, abort the call
        caching: collectionCachingNoPagination,
        // If the member is not a moderator or administrator, remove any moderatorOnly tags
        transformResponse: response => {
          const apiEntity = adminOrModerator
            ? response.data
            : response.data.filter(tag => tag.moderatorOnly === adminOrModerator);
          return {
            data: apiEntity,
          };
        },
      },
    ),
  );
});

export const CREATE_COMMUNITY_POST = 'communityActions/CREATE_COMMUNITY_POST';

/**
 * Creates a new post in the community
 * @param title {string} The title of the post
 * @param text {string} The text content of the post
 * @param tags {Array<number>} An array of tag ids to attach to the post
 * @param images {Array<string>} An array of base64 encoded image strings
 * @param communityGroupId {string} (Optional) The member group id which the post is associated to
 * @param containerId {string} (Optional) The groups id
 */
export const createCommunityPost = (
  title,
  text,
  tags,
  images,
  communityGroupId,
  containerId,
) => dispatch =>
  dispatch(
    apiPost(CREATE_COMMUNITY_POST, GATEWAY_COMMUNITY_V2_AUTH, '/posts', {
      title,
      text,
      tags,
      media: imageInputRESTFormatter(images),
      communityGroupId,
      containerId,
    }),
  ).then(data => {
    dispatch(collectionClearAll(communityPostsCollectionId()));
    dispatch(collectionClearAll(communityGroupPostsCollectionId()));

    return data;
  });

export const EDIT_COMMUNITY_POST = 'communityActions/EDIT_COMMUNITY_POST';

export const editCommunityPost = (previousPost, title, text, tags, images) => dispatch => {
  const newImage = (images && images[0]) || null;
  const oldImage = (previousPost && previousPost.media && previousPost.media.content) || null;
  const data = { title, text, tags };

  if (newImage !== oldImage) {
    if (newImage) {
      data.media = imageInputRESTFormatter(images);
    } else {
      data.deleteMedia = true;
    }
  }

  return dispatch(
    apiPatch(EDIT_COMMUNITY_POST, GATEWAY_COMMUNITY_V2_AUTH, `/posts/${previousPost.id}`, data),
  ).then(({ data: { media, mentions } }) =>
    dispatch(
      setEntity(
        POST,
        previousPost.id,
        {
          tags: (tags || []).map(tag => (typeof tag === 'number' ? tag : parseInt(tag, 10))),
          title,
          text,
          media,
          mentions,
        },
        true,
      ),
    ),
  );
};

export const CREATE_COMMUNITY_COMMENT = 'communityActions/CREATE_COMMUNITY_COMMENT';

export const createCommunityComment = (
  discussionId,
  discussionTitle,
  discussionKind,
  message,
  parentId = null,
  images = [],
) => dispatch =>
  dispatch(
    apiPost(CREATE_COMMUNITY_COMMENT, GATEWAY_COMMUNITY_V2_AUTH, '/comments', {
      message,
      discussionKind,
      discussionId,
      discussionTitle,
      ...(parentId ? { parentId } : {}),
      media: imageInputRESTFormatter(images),
    }),
  );

export const EDIT_COMMUNITY_COMMENT = 'communityActions/EDIT_COMMUNITY_COMMENT';

export const editCommunityComment = (id, previousMedia, message, images = []) => dispatch => {
  const newImage = (images && images[0]) || null;
  const oldImage = (previousMedia && previousMedia.content) || null;
  const data = { message };

  if (newImage !== oldImage) {
    if (newImage) {
      data.media = imageInputRESTFormatter(images);
    } else {
      data.deleteMedia = true;
    }
  }

  return dispatch(
    apiPatch(EDIT_COMMUNITY_COMMENT, GATEWAY_COMMUNITY_V2_AUTH, `/comments/${id}`, data),
  ).then(({ data: { media, mentions } }) =>
    dispatch(
      setEntity(
        COMMENT,
        id,
        {
          message,
          media,
          mentions,
        },
        true,
      ),
    ),
  );
};

export const REPORT_POST = 'communityActions/REPORT_POST';

export const reportPost = id =>
  apiPost(REPORT_POST, GATEWAY_COMMUNITY_AUTH, `/posts/${id}/reports`);

export const DELETE_POST = 'communityActions/DELETE_POST';

export const deletePost = id => dispatch =>
  dispatch(apiDelete(DELETE_POST, GATEWAY_COMMUNITY_AUTH, `/posts/${id}`)).then(() => {
    /*
    It's getting the same post to check
    if the comment has been deleted and update it
  */
    dispatch(apiGet(GET_POST_DETAIL, GATEWAY_COMMUNITY_AUTH, `/posts/${id}`))
      .then(result => {
        dispatch(setEntity(POST, id, result.data, true));
      })
      .catch(e => {
        // In case 404 it should be removed from collections and entities
        if (e instanceof GatewayError && e.response.status === 404) {
          // remove post from community overview
          dispatch(collectionRemoveRefs(communityPostsCollectionId(), [{ id, type: POST }]));
          // remove post from related posts
          dispatch(
            collectionClearIfContainsRef(communityRelatedPostsCollectionId(), [{ id, type: POST }]),
          );
          dispatch(removeEntities([id], POST));
        }
      });
  });

export const REPORT_COMMENT = 'communityActions/REPORT_COMMENT';

export const reportComment = id =>
  apiPost(REPORT_COMMENT, GATEWAY_COMMUNITY_AUTH, `/comments/${id}/reports`);

export const DELETE_COMMENT = 'communityActions/DELETE_COMMENT';
export const GET_COMMENT = 'communityActions/GET_COMMENT';

export const deleteComment = (id, discussionId, isReply, parentId) => dispatch =>
  dispatch(apiDelete(DELETE_COMMENT, GATEWAY_COMMUNITY_AUTH, `/comments/${id}`)).then(() => {
    /*
      It's getting the same comment to check
      if the comment has been deleted and update it
    */
    dispatch(apiGet(GET_COMMENT, GATEWAY_COMMUNITY_AUTH, `/comments/${id}`))
      .then(result => {
        dispatch(setEntity(COMMENT, id, result.data, true));
      })
      .catch(e => {
        // In case 404 It should be removed from collections and entities
        if (e instanceof GatewayError && e.response.status === 404) {
          // remove comment from community/post overview
          dispatch(
            collectionRemoveRefs(
              communityCommentsCollectionId({
                parentId: isReply ? parentId : discussionId,
                parentIsComment: isReply,
              }),
              [{ id, type: COMMENT }],
            ),
          );
          dispatch(removeEntities([id], COMMENT));
          if (!isReply) {
            dispatch(updateCommentsCountPost(discussionId, -1));
          }
        }
      });
  });

export const updateCommentsCountPost = (postId, count) => (dispatch, getState) => {
  const state = getState();
  const posts = state.entities[POST];
  const post = posts ? posts[postId] : null;

  if (post) {
    const commentsCount = (post.commentsCount || 0) + count;

    return dispatch(setEntity(POST, postId, { commentsCount }, true));
  }
  return {};
};

export const GET_COMMUNITY_USERNAMES = 'communityActions/GET_COMMUNITY_USERNAMES';

export const getCommunityMentions = username => dispatch =>
  dispatch(
    apiGet(GET_COMMUNITY_USERNAMES, GATEWAY_COMMUNITY_AUTH, `/mentions?userName=${username}`),
  ).then(result => {
    // Map data into correct shape for draft-js mention component
    const members = result.data.map(member => ({
      id: member.id,
      name: member.userName,
      avatar: member.avatar,
    }));

    return members;
  });

export const GET_COMMUNITY_GROUP_POSTS = 'communityActions/GET_COMMUNITY_GROUP_POSTS';

export const getCommunityGroupPosts = (
  slug,
  {
    tags = 0,
    onlyMe,
    sort,
    postType,
    isDeleted = false,
    includeCommunityGroupPinnedFirst = false,
    loadMore = true,
    includeTrending,
    includeLastLike = true,
    limit = 10,
    useCursorPagination = true,
  },
  containerId = null,
  getFresh = false,
) => dispatch => {
  const { requestData, requestPagination } = buildPostFilters({
    tags,
    onlyMe,
    sort,
    postType,
    isDeleted,
    includeCommunityGroupPinnedFirst,
    loadMore,
    includeTrending,
    includeLastLike,
    limit,
    useCursorPagination,
    containerId,
  });

  return dispatch(
    apiGetCollection(
      GET_COMMUNITY_GROUP_POSTS,
      GATEWAY_COMMUNITY_AUTH,
      `/community-groups/${slug}/posts`,
      communityGroupPostsCollectionId({
        slug,
        tags,
        onlyCurrentUser: onlyMe,
        postType,
        containerId,
        sort,
      }),
      requestPagination,
      {
        updatePaginationView: {
          target: COMMUNITY_GROUP_POSTS,
          extend: true,
        },
        requestData,
        entityType: POST,
        caching: getFresh ? false : undefined,
        transformResponse: response => {
          // eslint-disable-next-line no-unused-vars
          const { total: removeTotal, ...paginationWithoutTotal } = response.pagination;

          return {
            ...response,
            pagination: {
              ...paginationWithoutTotal,
            },
          };
        },
        transformEntity: transformNormalizePost,
      },
    ),
  ).then(({ result }) => {
    dispatch(
      addCommunityGroupEntitiesFromPosts(
        result.data,
        getDefaultApiEntityTransform(`/community-groups/${slug}/posts`, GET_COMMUNITY_GROUP_POSTS),
      ),
    );
  });
};

export const GET_COMMUNITY_GROUP = 'communityActions/GET_COMMUNITY_GROUP';

export const getCommunityGroup = slug => async dispatch =>
  dispatch(
    apiGetEntity(
      GET_COMMUNITY_GROUP,
      GATEWAY_COMMUNITY_AUTH,
      `/community-groups/${slug}`,
      COMMUNITY_GROUP,
      {
        findEntity: entity => entity.slug === slug,
        getId: entity => entity.id,
      },
      {},
    ),
  );

export const JOIN_COMMUNITY_GROUP = 'communityActions/JOIN_COMMUNITY_GROUP';

export const joinCommunityGroup = communityGroupId => async (dispatch, getState) => {
  await authenticate();
  const userId = userIdSelector(getState());

  dispatch(
    apiPost(
      JOIN_COMMUNITY_GROUP,
      GATEWAY_COMMUNITY_AUTH,
      `/profiles/${userId}/community-groups/${communityGroupId}`,
    ),
  ).then(() => {
    // get current members count so we can increment it
    const state = getState();
    const { membersCount } = state.entities[COMMUNITY_GROUP][communityGroupId];
    dispatch(
      setEntity(
        COMMUNITY_GROUP,
        communityGroupId,
        { hasJoined: true, membersCount: membersCount + 1 },
        true,
      ),
    );

    // clear community posts collection so the community feed is re-fetched
    dispatch(collectionClearAll(communityPostsCollectionId()));
  });
};

export const LEAVE_COMMUNITY_GROUP = 'communityActions/LEAVE_COMMUNITY_GROUP';

export const leaveCommunityGroup = communityGroupId => async (dispatch, getState) => {
  await authenticate();
  const userId = userIdSelector(getState());

  dispatch(
    apiDelete(
      LEAVE_COMMUNITY_GROUP,
      GATEWAY_COMMUNITY_AUTH,
      `/profiles/${userId}/community-groups/${communityGroupId}`,
    ),
  ).then(() => {
    // get current members count so we can decrement it
    const state = getState();
    const { membersCount } = state.entities[COMMUNITY_GROUP][communityGroupId];

    dispatch(
      setEntity(
        COMMUNITY_GROUP,
        communityGroupId,
        { hasJoined: false, membersCount: membersCount - 1 },
        true,
      ),
    );

    // clear community posts collection so the community feed is re-fetched
    dispatch(collectionClearAll(communityPostsCollectionId()));
  });
};

export const GET_MEMBER_COMMUNITY_GROUPS = 'communityActions/GET_MEMBER_COMMUNITY_GROUPS';

export const getMemberCommunityGroups = () => async (dispatch, getState) => {
  await authenticate();
  const userId = userIdSelector(getState());

  return dispatch(
    apiGetCollection(
      GET_MEMBER_COMMUNITY_GROUPS,
      GATEWAY_COMMUNITY_AUTH,
      `/profiles/${userId}/community-groups`,
      COMMUNITY_MEMBER_GROUPS,
      {},
      {
        useCache: false,
        entityType: COMMUNITY_GROUP,
      },
    ),
  );
};

export const GET_ALL_COMMUNITY_GROUPS = 'communityActions/GET_ALL_COMMUNITY_GROUPS';

export const getCommunityGroups = () => async dispatch =>
  dispatch(
    apiGetCollection(
      GET_ALL_COMMUNITY_GROUPS,
      GATEWAY_COMMUNITY_AUTH,
      '/community-groups',
      COMMUNITY_GROUPS,
      {},
      {
        entityType: COMMUNITY_GROUP,
      },
    ),
  );

const buildPostFilters = ({
  tags = 0,
  onlyMe,
  sort,
  postType,
  isDeleted = false,
  includePinnedFirst = false,
  includeCommunityGroupPinnedFirst = false,
  loadMore = true,
  includeTrending,
  includeLastLike = true,
  limit = 10,
  useCursorPagination = true,
  containerId = null,
}) => {
  const requestData = {
    includeLastLike,
    postType: postType || PostType.POST,
    sort: sort || SortType.NEWEST,
    includePinnedFirst,
    includeCommunityGroupPinnedFirst,
    isDeleted,
    includeTrending,
  };

  if (onlyMe) {
    requestData.onlyCurrentUser = true;
  }
  if (containerId) {
    requestData.containerId = containerId;
  }
  if (tags) {
    requestData.tags = convertBitwiseToArray(tags).join(',');
  }

  const requestPagination = { limit };
  const sortArray = [SortType.OLDEST, SortType.LATEST_ACTIVITY_DATE, SortType.MOST_LIKED];

  // only do cursor based pagination when sorting is on 'id'
  if (
    (requestData.sort.endsWith('id') && useCursorPagination) ||
    sortArray.some(item => requestData.sort.endsWith(item))
  ) {
    requestPagination.from = {
      key: 'id',
      param: 'sinceId',
    };
    if (requestData.sort.endsWith(SortType.LATEST_ACTIVITY_DATE)) {
      requestPagination.andFrom = {
        key: 'latestActivityDate',
        param: 'sinceSortFieldValue',
      };
    } else if (requestData.sort.endsWith(SortType.MOST_LIKED)) {
      requestPagination.andFrom = {
        key: 'likesCount',
        param: 'sinceSortFieldValue',
      };
    }
  } else {
    requestPagination.offset = loadMore ? GET_NEXT : 0;
  }

  return { requestData, requestPagination };
};

const transformNormalizePost = post => {
  // eslint-disable-next-line no-unused-vars
  const { communityGroup: remove, ...postNormalized } = post;

  return {
    communityGroupId: post?.communityGroup?.id || null,
    ...postNormalized,
  };
};

const addCommunityGroupEntitiesFromPosts = (data, transformEntity) => dispatch => {
  const entities = Array.isArray(data) ? data : [data];

  const communityGroups = entities
    .filter(
      ({ communityGroup }) => communityGroup !== null && typeof communityGroup !== 'undefined',
    )
    .map(({ communityGroup }) => communityGroup);

  dispatch(addEntitiesFromApiData(communityGroups, COMMUNITY_GROUP, undefined, transformEntity));
};