Re: User.js

From disqus.com, 2 Months ago, written in JavaScript, viewed 3 times. This paste is a reply to Re: Re: Session.js from disqus.com - view diff
URL https://pastebin.freepbx.org/view/45e529c9 Embed
Download Paste or View Raw
  1. define('core/models/User',[
  2.     'jquery',
  3.     'underscore',
  4.     'moment',
  5.  
  6.     'core/config',
  7.     'core/time',
  8.     'core/utils',
  9.     'core/strings',
  10.     'core/api',
  11.  
  12.     'core/models/BaseUser',
  13. ], function (
  14.     $,
  15.     _,
  16.     moment,
  17.  
  18.     config,
  19.     time,
  20.     utils,
  21.     strings,
  22.     api,
  23.     BaseUser
  24. ) {
  25.     'use strict';
  26.  
  27.     var gettext = strings.get;
  28.  
  29.     function addError(validationErrors, name, error) {
  30.         validationErrors[name] = validationErrors[name] || [];
  31.         validationErrors[name].push(error);
  32.     }
  33.  
  34.     // WARNING: Do not create User objects directly. Use UniqueModel instead.
  35.     var User = BaseUser.extend({
  36.         url: api.getURL('users/details'),
  37.  
  38.         validate: function (attrs) {
  39.             // THOUGHT: I'm not sure that we should be calling gettext
  40.             //          from the model. I think we should have the view
  41.             //          do that. Coupling, etc.
  42.             var validationErrors = {};
  43.  
  44.             if (attrs.display_name)
  45.                 attrs.display_name = $.trim(attrs.display_name);
  46.  
  47.             if (!attrs.display_name)
  48.                 addError(validationErrors, 'display_name', gettext('Please enter your name.'));
  49.  
  50.             if (!attrs.email)
  51.                 addError(validationErrors, 'email', gettext('Please enter your email address.'));
  52.  
  53.             if (!utils.validateEmail(attrs.email))
  54.                 addError(validationErrors, 'email', gettext('Invalid email address.'));
  55.  
  56.             if (this.isNew()) {
  57.                 if (!attrs.password)
  58.                     addError(validationErrors, 'password', gettext('Please enter a password.'));
  59.  
  60.                 else if (attrs.password.length < User.MIN_PASSWORD_LEN)
  61.                     addError(validationErrors, 'password', gettext('Password must have at least 6 characters.'));
  62.             }
  63.  
  64.             if (attrs.name) {
  65.                 if (attrs.name.length < User.MIN_NAME_LEN) {
  66.                     addError(validationErrors, 'name', strings.interpolate(
  67.                         gettext('Name must have at least %(minLength)s characters.'),
  68.                         { minLength: User.MIN_NAME_LEN }
  69.                     ));
  70.                 }
  71.  
  72.                 if (attrs.name.length > User.MAX_NAME_LEN) {
  73.                     addError(validationErrors, 'name', strings.interpolate(
  74.                         gettext('Name must have less than %(maxLength)s characters.'),
  75.                         { maxLength: User.MAX_NAME_LEN }
  76.                     ));
  77.                 }
  78.             }
  79.  
  80.             if (attrs.location) {
  81.                 if (attrs.location.length > User.MAX_LOCATION_LEN) {
  82.                     addError(validationErrors, 'location', strings.interpolate(
  83.                         gettext('Location must have less than %(maxLength)s characters.'),
  84.                         { maxLength: User.MAX_LOCATION_LEN }
  85.                     ));
  86.                 }
  87.             }
  88.  
  89.             if (attrs.url) {
  90.                 if (attrs.url.length > User.MAX_URL_LEN) {
  91.                     addError(validationErrors, 'url', strings.interpolate(
  92.                         gettext('Site must have less than %(maxLength)s characters.'),
  93.                         { maxLength: User.MAX_URL_LEN }
  94.                     ));
  95.                 }
  96.  
  97.                 if (!utils.isUrl(attrs.url))
  98.                     addError(validationErrors, 'url', gettext('Please enter a valid site.'));
  99.             }
  100.  
  101.             if (!_.isEmpty(validationErrors))
  102.                 return validationErrors;
  103.         },
  104.  
  105.         prepareFetchOptions: function (options) {
  106.             options = options ? _.clone(options) : {};
  107.  
  108.             var data = {};
  109.  
  110.             if (this.get('id'))
  111.                 data.user = this.get('id');
  112.             else if (this.get('username'))
  113.                 data.user = 'username:' + this.get('username');
  114.  
  115.             _.extend(data, options.data);
  116.             options.data = data;
  117.  
  118.             return options;
  119.         },
  120.  
  121.         fetch: function (options) {
  122.             options = this.prepareFetchOptions(options);
  123.             return BaseUser.prototype.fetch.call(this, options);
  124.         },
  125.  
  126.         parse: function (response) {
  127.             return response.response || response;
  128.         },
  129.  
  130.         register: function (options) {
  131.             var self = this;
  132.             options = options || {};
  133.  
  134.  
  135.             return api.call('internal/users/register.json', {
  136.                 data: _.extend(this.toRegisterJSON(), {
  137.                     gRecaptchaResponse: options.gRecaptchaResponse,
  138.                 }),
  139.                 method: 'POST',
  140.                 success: function (data) {
  141.                     api.call('users/acceptTerms', {
  142.                         method: 'POST',
  143.                     });
  144.                     self.set(_.extend({}, data.response, {
  145.                         // To speed up the signup process, assume the acceptTerms endpoint
  146.                         // call will succeed
  147.                         hasAcceptedGdprTerms: true,
  148.                     }));
  149.                     if (options.success)
  150.                         options.success(data);
  151.                 },
  152.                 error: options.error,
  153.             });
  154.         },
  155.  
  156.         /*
  157.          * This method uses FormData which isn't supported in all browsers.
  158.          * The Onboard.ProfileSectionView uses this method but checks to see
  159.          * if FormData is supported first.
  160.          */
  161.         saveAvatar: function (fileInput) {
  162.             var formData = new window.FormData();
  163.             formData.append('avatar_file', fileInput);
  164.             formData.append('api_key', config.keys.api);
  165.  
  166.             return api.call('internal/users/updateAvatar.json', {
  167.                 method: 'post',
  168.                 data: formData,
  169.                 cache: false,
  170.                 contentType: false,
  171.                 processData: false,
  172.             });
  173.         },
  174.  
  175.         saveProfile: function () {
  176.             return api.call('users/updateProfile.json', {
  177.                 method: 'POST',
  178.                 data: {
  179.                     name: this.get('name'),
  180.                     about: this.get('about'),
  181.                     location: this.get('location'),
  182.                     url: this.get('url'),
  183.                 },
  184.             });
  185.         },
  186.  
  187.         toRegisterJSON: function () {
  188.             return _.pick(this.toJSON(), 'display_name', 'email', 'password');
  189.         },
  190.  
  191.         isSession: function (session) {
  192.             return session.user.id && session.user.id === this.id;
  193.         },
  194.  
  195.         isEditable: function (session) {
  196.             return this.isSession(session) && !this.get('remote');
  197.         },
  198.  
  199.         toJSON: function (options) {
  200.             options = options || {};
  201.  
  202.             var json = BaseUser.prototype.toJSON.call(this);
  203.             var thread = this.collection && this.collection.thread;
  204.  
  205.             json.thread.canModerate = Boolean(thread && thread.isModerator(this));
  206.  
  207.             // Optionally augment output JSON depending on active session
  208.             if (options.session) {
  209.                 json.isSession = this.isSession(options.session);
  210.                 json.isEditable = this.isEditable(options.session);
  211.             }
  212.             return json;
  213.         },
  214.  
  215.         // Calls users/follow if state is true ("following"), users/unfollow
  216.         // if state is false ("not following")
  217.         _changeFollowState: function (state) {
  218.             this.set({
  219.                 isFollowing: state,
  220.                 numFollowers: Math.max(
  221.                     0,
  222.                     this.get('numFollowers') + (state ? 1 : -1)
  223.                 ),
  224.             });
  225.  
  226.             var endpoint = 'users/' + (state ? 'follow' : 'unfollow');
  227.  
  228.             // NOTE: If the server returns 200 with a *different* state value
  229.             //       than requested, we are ignoring that value. This should
  230.             //       be exceedingly rare (race condition).
  231.  
  232.             var self = this;
  233.  
  234.             return api.call(endpoint + '.json', {
  235.                 data: { target: this.get('id') },
  236.                 method: 'POST',
  237.                 success: function (resp) {
  238.                     self.trigger('sync', self, resp, {});
  239.                 },
  240.             });
  241.         },
  242.  
  243.         follow: function () {
  244.             return this._changeFollowState(true);
  245.         },
  246.  
  247.         unfollow: function () {
  248.             return this._changeFollowState(false);
  249.         },
  250.  
  251.         _changeBlockState: function (state) {
  252.             var endpoint = 'users/block/' + (state ? 'create' : 'delete');
  253.  
  254.             var self = this;
  255.             return api.call(endpoint + '.json', {
  256.                 data: { user: this.get('id') },
  257.                 method: 'POST',
  258.                 success: function (resp) {
  259.                     self.set(resp.response);
  260.                 },
  261.             });
  262.         },
  263.  
  264.         block: function () {
  265.             return this._changeBlockState(true);
  266.         },
  267.  
  268.         unblock: function () {
  269.             return this._changeBlockState(false);
  270.         },
  271.  
  272.         report: function (reason) {
  273.             var self = this;
  274.  
  275.             return api.call('users/report.json', {
  276.                 data: {
  277.                     reason: reason,
  278.                     user: this.get('id'),
  279.                 },
  280.                 method: 'POST',
  281.                 success: function () {
  282.                     self.set('isFlagged', true);
  283.                 },
  284.             });
  285.         },
  286.  
  287.         toggleFollowState: function () {
  288.             return this._changeFollowState(!this.get('isFollowing'));
  289.         },
  290.  
  291.         /*
  292.          * Checks to see if user was registered within a certain period.
  293.          */
  294.         registeredLessThan: function (num, period) {
  295.             var joinedAtUtc = time.assureTzOffset(this.get('joinedAt'));
  296.             var timePeriodAgo = moment().subtract(num, period);
  297.             return moment(joinedAtUtc).isAfter(timePeriodAgo);
  298.         },
  299.  
  300.         registeredToday: function () {
  301.             return this.registeredLessThan(1, 'day'); // ago
  302.         },
  303.  
  304.         registeredThisWeek: function () {
  305.             return this.registeredLessThan(1, 'week'); // ago
  306.         },
  307.  
  308.         /**
  309.          * Whether or not this user has completed onboarding in home.
  310.          * @returns {boolean}
  311.          */
  312.         shouldHomeOnboard: function () {
  313.             return !this.get('homeOnboardingComplete');
  314.         },
  315.  
  316.         /**
  317.          * Sets the flag for whether or not this user has completed
  318.          * onboarding in home.
  319.          * @param {boolean} isComplete denotes if user has completed home onboarding
  320.          */
  321.         setHomeOnboardComplete: function (isComplete) {
  322.             this.updateFlags({
  323.                 'homeOnboardingComplete': isComplete,
  324.             });
  325.  
  326.             // Sometimes, immediately after completing onboarding the app will receive this
  327.             // user's details through an api call and they have a falsey, out of date value for
  328.             // homeOnboardingComplete which overwrites this change. Since it's not possible
  329.             // to undo the completion of homeOnboarding from within the app, it's safe to
  330.             // persist the truthy value.
  331.             if (isComplete) {
  332.                 this.listenTo(this, 'change:homeOnboardingComplete',
  333.                     _.bind(this.set, this, 'homeOnboardingComplete', isComplete, { silent: true }));
  334.             }
  335.         },
  336.  
  337.         /*
  338.          * updateFlags expects an object with boolean values for flags:
  339.          * {
  340.          *     homeOnboardingComplete: true,
  341.          *     homeFeedOnboardingComplete: false
  342.          * }
  343.          *
  344.          * It will convert the boolean values to 1s and 0s for the api call
  345.          * as the UpdateFlags endpoint expects that.
  346.          */
  347.         updateFlags: function (flags) {
  348.             this.set(flags);
  349.  
  350.             return api.call('internal/users/updateFlags.json', {
  351.                 data: _.mapObject(flags, function (val) {
  352.                     return val ? 1 : 0;
  353.                 }),
  354.                 method: 'POST',
  355.             });
  356.         },
  357.     }, {
  358.         MIN_PASSWORD_LEN: 6,
  359.         MIN_NAME_LEN: 2,
  360.         MAX_NAME_LEN: 30,
  361.         MAX_LOCATION_LEN: 255,
  362.         MAX_URL_LEN: 200,
  363.     });
  364.  
  365.     return User;
  366. });
  367.  
  368. // https://c.disquscdn.com/next/next-core/core/models/User.js

Replies to Re: User.js rss

Title Name Language When
Re: Re: Router.js disqus.com javascript 2 Months ago.
Re: Thread.js disqus.com javascript 2 Months ago.

Reply to "Re: User.js"

Here you can reply to the paste above