models/communities/Activity.js

import User from './User';
import MediaAttachment from '../MediaAttachment';
import ActivityButton from './ActivityButton';
import UserReactions from './UserReactions';
import Mention from './Mention';
import CommunitiesEntity from './CommunitiesEntity';
import Poll from './Poll';
import { getLanguage, getLocalizedProperty } from '../../utils';

export default class Activity {
    /**
    * Creates a new Activity
    *
    * @constructor Activity
    * @param {object} activityMap - Activity parameters
    * @param {string} activityMap.id - ID
    * @param {string} [activityMap.text] - Text
    * @param {User} activityMap.author - Author
    * @param {MediaAttachment[]} [activityMap.mediaAttachments=[]] - Attachments
    * @param {ActivityButton} [activityMap.button] - Button
    * @param {string} [activityMap.type] - Type
    * @param {boolean} [activityMap.isAnnouncement=false] - True if is an announcement
    * @param {number} [activityMap.commentsCount=0] - Amount of comments
    * @param {Activity[]} [activityMap.comments=[]] - Comments (only included if includeComments is defined in the ActivitiesQuery)
    * @param {Object<string, number>} [activityMap.reactionsCount={}] - Amount of reactions per kind
    * @param {string[]} [activityMap.myReactions=[]] - Current user's reactions
    * @param {UserReactions[]} [activityMap.reactions=[]] - Reactions
    * @param {User[]} [activityMap.commenters=[]] - Commenters
    * @param {Object<string, string>} [activityMap.properties={}] - Properties
    * @param {number} [activityMap.createdAt=0] - Date when activity was created (UNIX timestamp)
    * @param {Mention[]} [activityMap.mentions=[]] - Users mentions
    * @param {CommunitiesEntity} [activityMap.source] - Entity source
    * @param {string} activityMap.status - Status
    * @param {Poll} [activityMap.poll] - Poll
    * @param {number} [activityMap.popularity=0] - Popularity
    * @param {string[]} [activityMap.labels=[]] - Labels
    * @param {boolean} [activityMap.isBookmarked=false] - True if is bookmarked
    * @param {number} [activityMap.bookmarksCount=0] - Amount of bookmarks
    */
    constructor(activityMap) {
        this.id = activityMap.id;
        this.text = activityMap.text || null;

        if (activityMap.author !== undefined &&
            activityMap.author != null) {
            this.author = User.create(activityMap.author);
        }

        this.mediaAttachments = [];
        const attachments = activityMap.mediaAttachments;
        if (attachments !== undefined && attachments != null) {
            attachments.forEach((attachmentMap) => {
                const attachment = new MediaAttachment(attachmentMap);
                this.mediaAttachments.push(attachment);
            });
        }

        if (activityMap.button != null) {
            this.button = new ActivityButton(activityMap.button);
        }

        this.type = activityMap.type;
        this.isAnnouncement = activityMap.isAnnouncement || false;
        this.commentsCount = activityMap.commentsCount || 0;

        this.comments = [];
        if (activityMap.comments !== undefined &&
            activityMap.comments != null) {
            activityMap.comments.forEach((commentMap) => {
                this.comments.push(Activity.create(commentMap));
            });
        }

        this.reactionsCount = activityMap.reactionsCount || {};
        this.myReactions = activityMap.myReactions || [];

        this.reactions = [];
        if (activityMap.reactions !== undefined &&
            activityMap.reactions != null) {
            activityMap.reactions.forEach((reactionMap) => {
                const reaction = new UserReactions(reactionMap);
                this.reactions.push(reaction);
            });
        }

        this.commenters = [];
        if (activityMap.commenters !== undefined &&
            activityMap.commenters != null) {
            activityMap.commenters.forEach((commenter) => {
                const user = User.create(commenter);
                this.commenters.push(user);
            });
        }

        this.properties = activityMap.properties || {};
        this.createdAt = activityMap.createdAt || 0;

        this.mentions = [];
        if (activityMap.mentions !== undefined &&
            activityMap.mentions != null) {
            activityMap.mentions.forEach((mentionMap) => {
                const mention = new Mention(mentionMap);
                this.mentions.push(mention);
            });
        }

        this.status = activityMap.status;

        if (activityMap.source !== undefined &&
            activityMap.source != null) {
            this.source = new CommunitiesEntity(activityMap.source);
        }

        if (activityMap.poll !== undefined &&
            activityMap.poll != null) {
            this.poll = new Poll(activityMap.poll);
        }

        this.popularity = activityMap.popularity || 0;
        this.labels = activityMap.labels || [];

        this.isBookmarked = activityMap.isBookmarked === true;
        this.bookmarksCount = activityMap.bookmarksCount || 0;

        Object.freeze(this);
    }

    /**
     * Create Activity from AFActivity
     *
     * @memberof Activity
     * @param {Object} activity - AFActivity
     * @returns {Activity} Activity instance
     * @ignore
     */
    static create(activity) {
        const poll = activity.poll;
        const lang = getLanguage(activity.content);
        const content = getLocalizedProperty(activity, 'content');
        const mentions = getLocalizedProperty(activity, 'mentions');

        return new Activity({
            ...activity,
            text: content
                ? content.text
                : null,
            mediaAttachments: content
                ? content.attachments
                : null,
            button: content && content.button
                ? {
                    title: content.button.buttonTitle,
                    action: content.button.action
                }
                : null,
            type: activity.contentType,
            commentsCount: activity.reactions.commentCount,
            comments: activity.reactions.comments,
            reactionsCount: activity.reactions.reactionCount,
            myReactions: activity.reactions.myReactions,
            commenters: activity.reactions.knownCommenters,
            reactions: activity.reactions.knownReactors
                ? activity.reactions.knownReactors
                    .map((reactor) => {
                        return {
                            user: reactor.creator,
                            reactions: reactor.reactions
                        };
                    })
                : null,
            mentions: mentions
                ? mentions.map((mention) => {
                    return {
                        userId: mention.userId,
                        type: mention.mentionType,
                        startIndex: mention.startIdx,
                        endIndex: mention.endIdx
                    };
                })
                : [],
            source: {
                ...activity.source,
                id: activity.source.id.id,
                type: activity.source.id.entityType,
                title: getLocalizedProperty(activity.source, 'title'),
                isFollowedByMe: activity.source.isFollower
            },
            poll: poll
                ? {
                    allowMultipleVotes: poll.allowMultiVotes,
                    endDate: poll.endsAt,
                    options: poll.pollOptions
                        ? poll.pollOptions.map((option) => {
                            return {
                                ...option,
                                ...option.content[lang],
                                optionId: option.id
                            }
                        })
                        : null,
                    totalVotes: poll.voteCount,
                    voters: poll.knownVoters
                        ? poll.knownVoters.map((voter) => {
                            return {
                                user: voter.creator,
                                votes: voter.optionIds
                            }
                        })
                        : null
                }
                : null,
            popularity: activity.score,
            bookmarksCount: activity.reactions.bookmarkCount,
            isBookmarked: activity.reactions.isBookmarked
        });
    }
}