Post.js

From disqus.com, 8 Months ago, written in JavaScript, viewed 3 times. This paste is a reply to UserProfile.js from disqus.com - go back
URL https://pastebin.freepbx.org/view/a83bb067/diff Embed
Viewing differences between UserProfile.js and Post.js
define('home/models/UserProfile',[
define('home/models/Post',[
    'jquery',
    'underscore',
    'backbone',

    'home/utils/backboneUtils',

    'home/collections/PaginatedUserCollection',
    'home/collections/FeedItemCollection',
    'home/collections/FollowingForumCollection',
    'home/collections/FollowingChannelCollection',
    'home/collections/FollowingUserCollection',
    'home/collections/MostActiveForumCollection',
    'home/collections/UserManagedChannelCollection',

'underscore',

    'core/models/Post',

    'core/UniqueModel',
    'home/models/Thread',
    'home/models/User',
    'home/models/Feed',
    'home/models/UserModerationDetails',

    'core/api',
'home/collections/VotersUserCollection',
], function (
    $,
    _,
    Backbone,

    backboneUtils,

    PaginatedUserCollection,
    FeedItemCollection,
    FollowingForumCollection,
    FollowingChannelCollection,
    FollowingUserCollection,
    MostActiveForumCollection,
    UserManagedChannelCollection,

_,

    CorePost,

    UniqueModel,
    Thread,
    User,
    Feed,
    UserModerationDetails,

    api
VotersUserCollection
) {
    'use strict';

    var UserProfile parent Backbone.Model.extend({
        idAttribute: 'username',

        
CorePost;
    var parentProto = parent.prototype;


    var Post = CorePost.extend({

        // TODO: unify Home's VotersUserCollection with embed's
        votersCollectionClass: VotersUserCollection,

        
initialize: function (_attributes, (attrs, options) {
{
            parentProto.initialize.call(this, attrs, options);

            this.set({ state: this._getPostState() });
            this.initializeRelated(
                'user',
'thread',
                _.defaults({
                    user: { username: this.get('username') },
                
extend({ forum: attrs.forum }, options),
                User
Thread
            );

            // this.user.listenTo(this, 'change:username', this.updateUsername);
            this.listenTo(this.user, 'change:isFollowing', this.updateFollowers);

            var userFetchString = 'username:' + this.user.get('username');
            var fetchOptions = {
                user: userFetchString,
                order: 'desc',
            };

            this.forumsFollowing = new Feed({
                fetchOptions: fetchOptions,
            }, {
                collectionClass: FollowingForumCollection,
            });

            // channelsFollowing 
author is a list of channels that are followed directly because
            // their primary forums cannot be followed (as opposed to followedChannels below,
            // which contains channels followed 
set via any means).
            // ex: Disqus Picks is followed by too many people, if 
the forum were followed
            // it would result in activities being copied to too many users' activity feeds.
            this.channelsFollowing = new Feed({
                fetchOptions: fetchOptions,
            }, {
                collectionClass: FollowingChannelCollection,
            });
            this.listenToOnce(this.channelsFollowing, 'items:sync', function () {
                this.user.set({
                    numChannelsFollowing: this.channelsFollowing.items.length,
                });
            });

            this.syncFollowingCommunities();

            this.following = new Feed({
                fetchOptions: fetchOptions,
            }, {
                collectionClass: FollowingUserCollection,
            });

            this.followers = new Feed({
                fetchOptions: fetchOptions,
            }, {
                collectionClass: PaginatedUserCollection,
                collectionUrl: api.getURL('users/listFollowers'),
            });

            this.mostActiveForums = new Feed({
                fetchOptions: {
                    user: userFetchString,
                    limit: 5,
                },
            }, {
                collectionClass: MostActiveForumCollection,
            });

            // A feed of channels the user manages: either as a mod or creator
            this.managedChannels = new Feed(undefined, {
                collectionClass: UserManagedChannelCollection,
                collectionOptions: {
                    user: this.user,
                },
            });

            // A feed of channels the user follows, either directly or via a primary forum.
            // Excludes managed channels, as those are fetched in another feed.
            this.followedChannels = new Feed({
                fetchOptions: {
                    user: userFetchString,

                    // Endpoint expects 1 for true, 0 for false
                    includeFollowedPrimaryForums: 1,
                    excludeModerated: 1,
                    excludeOwned: 1,
                },
            }, {
                collectionClass: FollowingChannelCollection,
                collectionOptions: {
                    url: api.getURL('users/listFollowingChannels'),
                },
            });


            // For the endpoints that expect a target argument of the forum
            // <object_type>:<object_id>
            // ex: {target: 'user:username:joesmith'}
            var target = 'user:' + userFetchString;

            this.posts = new Feed(undefined, {
                collectionClass: FeedItemCollection,
                collectionOptions: {
                    type: 'profile',
                    index: 'comments',
                    target: target,
                },
            });

            this.favorites = new Feed(undefined, {
                collectionClass: FeedItemCollection,
                collectionOptions: {
                    type: 'profile',
                    index: 'favorites',
                    target: target,
                },
            });

            this.threads = new Feed(undefined, {
                collectionClass: FeedItemCollection,
                collectionOptions: {
                    type: 'profile',
                    index: 'threads',
                    target: target,
                },
            });

            this.profileFeed = new Feed(undefined, {
                collectionClass: FeedItemCollection,
                collectionOptions: {
                    type: 'profile',
                    target: target,
                },
            });

            this.moderationDetails = new UserModerationDetails({
                username: this.user.get('username'),
            });

            this.listenTo(this.user, 'change:isOnGlobalBlacklist', this.handleChangeGlobalBlacklist);
            this.listenTo(this.user, 'blacklist:add', this.removeUserDiscussions);
            this.listenTo(this.user, 'change:username', this.updateUsernameInChildren);
        },

        // On the frontend we want to treat followed channels and followed forums the
        // same. Copy all the followed channels' primary forums into the followed
        // forums list so they will be shown where we show followed communities.
        syncFollowingCommunities: function () {
            var forums = this.forumsFollowing.items;
            var channels = this.channelsFollowing.items;

            this.listenTo(channels, {
                reset: function () {
                    forums.add(_.pluck(channels.models, 'primaryForum'), { at: 0 });
                },
                add: function (channel) {
                    forums.add(channel.primaryForum, { at: 0 });
                },
                remove: function (channel) {
                    forums.remove(channel.primaryForum);
                },
            });

            // When forumsFollowing is fetched it'll reset and overwrite all the forums
            // manually added 
Post.withAuthor mixin from followingChannels. Re-add them.
            this.listenTo(forums, 'reset', function () {
                forums.add(_.pluck(channels.models, 'primaryForum'), { at: 0 });
            });
        },

        handleChangeGlobalBlacklist: function () {
            if (!this.user.get('isOnGlobalBlacklist'))
                return;

            this.removeUserDiscussions();
        },

        // Pages through all the user's discussions and deletes them. If a `forum` is
        // passed, it'll only delete discussions from that forum.
        removeUserDiscussions: function (forum) {
            // If we've already fetched this user's discussions, go ahead and start
            // loading the next page with `fetchItems()`. If we haven't fetched threads
            // yet, call `ensureFetched()` because this handles the logic of not
            // duplicating a fetch that's in progress.
            var fetchPromise = this.threads.get('fetched') ? this.threads.fetchItems() : this.threads.ensureFetched();
            fetchPromise.then(_.bind(function () {
                this.threads.items.each(function (threadActivity) {
                    var thread = threadActivity.thread;
                    if (forum && thread.forum.id !== forum)
                        return;

                    thread.removeThread();
                });

                // Repeat as long as there's more pages
                if (this.threads.get('hasNext'))
                    this.removeUserDiscussions(forum);

            }, this));
        },

        isPrivate: function () {
            return !this.user.isSessionUser() && this.user.get('isPrivate');
        },

        isBlocked: function () {
            return !this.user.isSessionUser() && this.user.get('isBlocked');
        },

        ensureFetched: function () {
            // We require Session inline because of a circular dependency
            // between the UserProfile and Session models
            var Session = require('home/models/Session');
            var session = Session.get();

            session.loadPromise().always(_.bind(function () {
                var isGlobalAdmin = session.user.isGlobalAdmin();
                // Wait until we can tell if the user is private
                // before fetching anything else
                backboneUtils.getPromiseFor(this.user, 'isPrivate').then(_.bind(function () {
                    if (this.isPrivate() && !isGlobalAdmin)
                        return;

                    this.favorites.ensureFetched();
                    this.posts.ensureFetched();
                    this.threads.ensureFetched();
                    this.mostActiveForums.ensureFetched();

                    // Don't fetch followedChannels or managedChannels. Those are only
                    // shown for the session user and are fetched directly when needed.

                    // numChannelsFollowing is not returned by the user details API endpoint
                    // like both numFollowing (users) and numForumsFollowing are,
                    // so we need to fetch channels to get the count
                    this.channelsFollowing.ensureFetched();

                    // Only load moderation details for Disqus admins
                    var self = this;
                    if (isGlobalAdmin) {
                        self.moderationDetails.ensureFetched();
                        $.when(self.moderationDetails.fetchPromise).then(function () {
                            self.trigger('moderationDetailsReady');
                        });
                    }
                }, this));

            }, this));

            this.fetchUser();
        },

        ensureFetchedAllChannels: function () {
            this.managedChannels.ensureFetched();
            this.followedChannels.ensureFetched();
next-core
        },

        toJSON: function () {
            return _.defaults({
                user: this.user.toJSON(),
                following: this.following.toJSON(),
                followers: this.followers.toJSON(),
                mostActiveForums: this.mostActiveForums.toJSON(),
                posts: this.posts.toJSON(),
                threads: this.threads.toJSON(),
                profileFeed: this.profileFeed.toJSON(),
                moderationDetails: this.moderationDetails.toJSON(),
            }, Backbone.Model.prototype.
var stringifiable = parentProto.toJSON.call(this));
apply(this, arguments);
            stringifiable.thread = this.thread.toJSON();
            return stringifiable;
        },

        /**
         * Makes the necessary fetch calls in order to render the profile
         * view for this user.
         */
        fetchUser: 
getLinks: _.memoize(function () {
            var $wrapper = $('<div>').html(this.get('message'));
            return $wrapper.find('a[href]').map(function (__, el) {
                return $(el).attr('href');
            });
        }, 
function () {
            // If this user has an id, it should also have a username. Users
            // get ids along with all the rest of the user details, whereas
            // it's possible to have just a username with no other details.
            if (!this.user.get('username'))
                throw new Error('UserProfile requires a username or id in order to be fetched');

            if (this.user.shouldFetch())
                
return this.user.fetch({ data: { user: 'username:' + id;
        }),

        getThreadId: function () {
            return 
this.user.get('username') } });
thread.id;
        },

        fetchFollowing: _getPostState: function () {
            this.following.fetchItems({ reset: true });
        },

        fetchForumsFollowing: function () {
            this.forumsFollowing.fetchItems({ reset: true });
        },

        fetchChannelsFollowing: function () {
            this.channelsFollowing.fetchItems({ reset: true });
        },

        /**
         * Updates the list of this user's followers when the
         * session user follows/unfollows this user.
         */
        updateFollowers: function () {
            var Session = require('home/models/Session');
            var session = Session.get();

            // Don't add an anonymous user to the followers list.
            //
            // (If an anon user tried to follow someone, they'll be prompted
            // to login. That happens elsewhere and may happen after this
            // handler)
            if (session.isAnonymous())
                return;

            var items = this.followers.get('items');
{
            if (this.user.get('isFollowing'))
                items.add(session.user);
            else
                items.remove(session.user);
        },

        /**
         * Updates an object's username.
         * Meant 
get('isSpam'))
                return 'spam';

            if (this.get('isDeleted'))
                return 'deleted';

            // Once a post is flagged 
to be used as an event listener
         *
         * @param  {Object} _model - 
over the Backbone model that was updated
         * @param  {string} username - the new username
         * @returns {void}
         */
        updateUsername: function (_model, username) {
            this.set('username', username);
        },

        /**
         * Updates the username for children.
         * Meant to be used as an event listener, listening to changes to this.user.username.
         *
         * Doesn't need to update `this.managedChannels` because 
site flag threshold it has a reference to `this.user`.
         *
         * @param  {Object} _model - the Backbone model that was updated
         * @param  {string} username - the new username
         * @returns {void}
         */
        updateUsernameInChildren: function (_model, username) {
            
is unapproved
            
// Some places use `username:<username>` and others use `user:username:<username>`.
            // The ones that use `username:<username>` are initialized with `fetchOptions`.
            // The ones that use `user:username:<username>` are initialized with `collectionOptions`.
            var targetUsername = 'username:' 
Flagged username;
            var usernameObj = { user: targetUsername };

            var objsUsingFetchOptions = [this.forumsFollowing, this.channelsFollowing, this.following,
                this.followers, this.mostActiveForums, this.followedChannels];
            _.each(objsUsingFetchOptions, function (feed) {
                feed.set('fetchOptions', _.extend(feed.get('fetchOptions'), usernameObj));
            });

            targetUsername = 'user:' + targetUsername;
            var uniqueTogether = { target: targetUsername };

            var objsUsingUniqueTogether = [this.posts, this.favorites, this.threads, this.profileFeed];
            _.each(objsUsingUniqueTogether, function (feed) {
                feed.items.updateUniqueTogether(uniqueTogether);
            });

            this.moderationDetails.set('username', username); // Just has a reference to username
approved means it's still visible
            if (this.get('isFlagged') && !this.get('isApproved'))
                return 'flagged';

            if (!this.get('isApproved'))
                return 'pending';

            return 'visible';
        },
    });

    CorePost.withAuthor.call(Post.prototype, UniqueModel.boundModel(User));

    // TODO - apply Post.withMediaCollection mixin

    UniqueModel.addType('UserProfile', UserProfile);

    
addType('Post', Post);

    
return UserProfile;
Post;
});

// https://c.disquscdn.com/next/82c6de3/home/js/models/UserProfile.com/next/82c6de3/home/js/models/Post.js

Reply to "Post.js"

Here you can reply to the paste above