<commit_before>var config = require('../config');
var keystone = require('arch-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Video = new keystone.List('Video', {
    map: { name: 'title' },
	track: true,
    defaultSort: '-createTime',
});
var bucket = config['options']['gcs config']['bucket']

Video.add({
    title: { type: String, required: true, initial: true },
    sections: { label: '分區', type: Types.Relationship, ref: 'Section', many: true },
    categories: { label: '分類', type: Types.Relationship, ref: 'PostCategory', many: true },
    heroImage: { label: '首圖', type: Types.ImageRelationship, ref: 'Image' },
    description: { type: Types.Html, wysiwyg: true, height: 150 },
    video: {
        type: Types.GcsFile,
        initial: true,
        autoCleanup: true,
        datePrefix: 'YYYYMMDDHHmmss',
        bucket: bucket,
        destination: 'assets/videos/',
        publicRead: true,
    },
    tags: {
        type: Types.Relationship,
        ref: 'Tag',
        many: true
    },
    state: { label: '狀態', type: Types.Select, options: 'draft, published, scheduled', default: 'draft', index: true },
	feed: { label: '供稿', type: Types.Boolean, default: true, index: true },
    publishedDate: { label: '發佈日期', type: Types.Datetime, index: true, utc: true, default: Date.now, dependsOn: { '$or': { state: [ 'published', 'scheduled' ] } }},
    relateds: { label: '相關文章', type: Types.Relationship, ref: 'Post', many: true },
    createTime: { type: Types.Datetime, default: Date.now, utc: true },
});

transform.toJSON(Video);
Video.defaultColumns = 'title, video, tags';
Video.register();
<commit_msg>rename the heroImage to coverPhoto<commit_after>var config = require('../config');
var keystone = require('arch-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Video = new keystone.List('Video', {
    map: { name: 'title' },
	track: true,
    defaultSort: '-createTime',
});
var bucket = config['options']['gcs config']['bucket']

Video.add({
    title: { type: String, required: true, initial: true },
    sections: { label: '分區', type: Types.Relationship, ref: 'Section', many: true },
    categories: { label: '分類', type: Types.Relationship, ref: 'PostCategory', many: true },
    coverPhoto: { label: '首圖', type: Types.ImageRelationship, ref: 'Image' },
    description: { type: Types.Html, wysiwyg: true, height: 150 },
    video: {
        type: Types.GcsFile,
        initial: true,
        autoCleanup: true,
        datePrefix: 'YYYYMMDDHHmmss',
        bucket: bucket,
        destination: 'assets/videos/',
        publicRead: true,
    },
    tags: {
        type: Types.Relationship,
        ref: 'Tag',
        many: true
    },
    state: { label: '狀態', type: Types.Select, options: 'draft, published, scheduled', default: 'draft', index: true },
	feed: { label: '供稿', type: Types.Boolean, default: true, index: true },
    publishedDate: { label: '發佈日期', type: Types.Datetime, index: true, utc: true, default: Date.now, dependsOn: { '$or': { state: [ 'published', 'scheduled' ] } }},
    relateds: { label: '相關文章', type: Types.Relationship, ref: 'Post', many: true },
    createTime: { type: Types.Datetime, default: Date.now, utc: true },
});

transform.toJSON(Video);
Video.defaultColumns = 'title, video, tags';
Video.register();
<|endoftext|>


<commit_before>var config = require('./config')
var mongoOp = require('./model/mongo')
var stringProcessor = require('./stringprocessor')
var dates = require('./dates')

// Example of promisifying
// function doSomething(input) {
//   console.log('hello' + input)
//   return Q.resolve();
// }

// const addReminder = (sendTo, familyId) => {
//
//   return Q.ninvoke(mongoOp.FamilyMembers, 'findOne', { 'name': sendTo, 'familyId': familyId }) //wraps n a promise
//   .catch(() => Q.reject('@' + sendTo + ' unkown sorry! 😕'))
//   //.then(doSomething) // automatically sends the result (the second parameter) to the function doSomething
//   .then(familyMember => {
//     return Q.ninvoke(mongoOp.Lists, 'findOne', {'listKey': config.remindersListKey, 'familyId': familyId})
//         .catch(() => Q.reject('second error')) // 'Second error' will be the actual error
//       })
// }

function addReminder (inputText, familyId, timeZone, callback) {
  var sendTo = stringProcessor.getFirstWord(inputText)
  var dateText = stringProcessor.removeFirstWord(inputText)
  dateText = dateText.replace('weekend', 'saturday')
  var generalError = 'Error creating reminder list 😦'

  // Q.ninvoke(mongoOp.FamilyMembers, 'findOne', { 'name': sendTo, 'familyId': familyId }) //wraps n a promise
  // .catch(() => Q.reject('@' + sendTo + ' unkown sorry! 😕'))
  // .then(doSomething) // automatically sends the result (the second parameter) to the function doSomething
  // .then(familyMember => {
  //
  //   return Q.ninvoke(mongoOp.Lists, 'findOne', {'listKey': config.remindersListKey, 'familyId': familyId})
  //       .catch(() => Q.reject('second error')) // 'Second error' will be the actual error
  //     })
  // .catch(err => {
  //   callback(err)
  // })

  mongoOp.FamilyMembers.findOne({ 'name': sendTo, 'familyId': familyId }, function (err, familyMember) {
    if ((familyMember == null || err) && (sendTo !== 'all')) {
      callback('@' + sendTo + ' unkown sorry! 😕')
    } else {
      var sendToId = familyMember.userId || config.allFamilyMembersID

      // Check lists and create if necessary
      mongoOp.Lists.findOne({'listKey': config.remindersListKey, 'familyId': familyId}, function (err, list) {
        if (err) callback(generalError)
        if (list == null) {
          var newList = new mongoOp.Lists({
            'listKey': config.remindersListKey,
            'listDescription': config.remindersListKey,
            'familyId': familyId
          })
          newList.save(function (err, data) {
            if (err) callback(generalError)
          })
        }
        dates.processDateAndTitleFromText(dateText, timeZone, function (err, date, localDateText, title) {
          if (err) {
            callback(err)
            return
          }

          if (title == null || title === '') {
            callback('Sorry need a reminder desciption 😦\nJust add one to the end.')
            return
          }

          // Create listItem
          var newItem = new mongoOp.ListItems({
            'listKey': config.remindersListKey,
            'listItemName': '@' + sendTo + ' ' + title + ' ' + localDateText,
            'familyId': familyId,
            'reminderWhen': date,
            'reminderUserId': sendToId,
            'reminderTitle': title
          })
          newItem.save(function (err, data) {
            if (err) callback('Error adding reminder 😦')
            else {
              console.log('----reminder saved: ' + inputText + ' Sherlocked:' + date + ' < ' + title)
              callback(null, 'Set for ' + localDateText + '.')
            }
          })
        })
      })
    }
  })
}

module.exports = {
  addReminder
}
<commit_msg>scheduler<commit_after>var config = require('./config')
var mongoOp = require('./model/mongo')
var stringProcessor = require('./stringprocessor')
var dates = require('./dates')

// Example of promisifying
// function doSomething(input) {
//   console.log('hello' + input)
//   return Q.resolve();
// }

// const addReminder = (sendTo, familyId) => {
//
//   return Q.ninvoke(mongoOp.FamilyMembers, 'findOne', { 'name': sendTo, 'familyId': familyId }) //wraps n a promise
//   .catch(() => Q.reject('@' + sendTo + ' unkown sorry! 😕'))
//   //.then(doSomething) // automatically sends the result (the second parameter) to the function doSomething
//   .then(familyMember => {
//     return Q.ninvoke(mongoOp.Lists, 'findOne', {'listKey': config.remindersListKey, 'familyId': familyId})
//         .catch(() => Q.reject('second error')) // 'Second error' will be the actual error
//       })
// }

function addReminder (inputText, familyId, timeZone, callback) {
  var sendTo = stringProcessor.getFirstWord(inputText)
  var dateText = stringProcessor.removeFirstWord(inputText)
  dateText = dateText.replace('weekend', 'saturday')
  var generalError = 'Error creating reminder list 😦'

  // Q.ninvoke(mongoOp.FamilyMembers, 'findOne', { 'name': sendTo, 'familyId': familyId }) //wraps n a promise
  // .catch(() => Q.reject('@' + sendTo + ' unkown sorry! 😕'))
  // .then(doSomething) // automatically sends the result (the second parameter) to the function doSomething
  // .then(familyMember => {
  //
  //   return Q.ninvoke(mongoOp.Lists, 'findOne', {'listKey': config.remindersListKey, 'familyId': familyId})
  //       .catch(() => Q.reject('second error')) // 'Second error' will be the actual error
  //     })
  // .catch(err => {
  //   callback(err)
  // })

  mongoOp.FamilyMembers.findOne({ 'name': sendTo, 'familyId': familyId }, function (err, familyMember) {
    if ((familyMember == null || err) && (sendTo !== 'all')) {
      callback('@' + sendTo + ' unkown sorry! 😕')
    } else {
      console.log('X1')
      var sendToId = familyMember.userId || config.allFamilyMembersID
      console.log('X2')

      // Check lists and create if necessary
      mongoOp.Lists.findOne({'listKey': config.remindersListKey, 'familyId': familyId}, function (err, list) {
        if (err) callback(generalError)
        if (list == null) {
          var newList = new mongoOp.Lists({
            'listKey': config.remindersListKey,
            'listDescription': config.remindersListKey,
            'familyId': familyId
          })
          newList.save(function (err, data) {
            if (err) callback(generalError)
          })
        }
        dates.processDateAndTitleFromText(dateText, timeZone, function (err, date, localDateText, title) {
          if (err) {
            callback(err)
            return
          }

          if (title == null || title === '') {
            callback('Sorry need a reminder desciption 😦\nJust add one to the end.')
            return
          }

          // Create listItem
          var newItem = new mongoOp.ListItems({
            'listKey': config.remindersListKey,
            'listItemName': '@' + sendTo + ' ' + title + ' ' + localDateText,
            'familyId': familyId,
            'reminderWhen': date,
            'reminderUserId': sendToId,
            'reminderTitle': title
          })
          newItem.save(function (err, data) {
            if (err) callback('Error adding reminder 😦')
            else {
              console.log('----reminder saved: ' + inputText + ' Sherlocked:' + date + ' < ' + title)
              callback(null, 'Set for ' + localDateText + '.')
            }
          })
        })
      })
    }
  })
}

module.exports = {
  addReminder
}
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var BBPromise = require('bluebird');
var model = require('hoist-model');
var Subscription = model.Subscription;
var Bucket = model.Bucket;
var BouncerToken = model.BouncerToken;
var ConnectorSetting = model.ConnectorSetting;
var SubscriptionWrapper = require('./subscription_wrapper');
var logger = require('hoist-logger');
var fs = require('fs');
var config = require('config');
var path = require('path');
var Authorization = require('hoist-connector-pipeline/lib/authorization');
var HoistContext = require('hoist-context');
var EventPipeline = require('hoist-events-pipeline');
var throat = require('throat')(BBPromise);
var moment = require('moment');

function PollerService() {

}

PollerService.prototype.start = function () {
  logger.info('starting poller service');
  //mark as running
  this.running = true;
  //start poll
  logger.info('starting loop');
  this.loop = this.poll().cancellable();
};
PollerService.prototype.stop = function () {
  return BBPromise.try(function () {
    logger.info('stopping poller service');
    //mark as stopped
    this.running = false;
    //cancel loop
    /* istanbul ignore else */
    if (this.loop) {
      if (this.loop.isCancellable()) {
        logger.info('cancelling loop');
        this.loop.cancel();
      } else {
        logger.warn('loop isn\'t cancellable for some reason');
      }
      //delete loop
      logger.info('deleting loop promise reference');
      delete this.loop;
    }
  }, [], this);

};
PollerService.prototype.poll = function () {
  //load subscriptions
  logger.info('loading subscriptions');
  return this.loadSubscriptions()
    .cancellable()
    .bind(this)
    //for each
    .then(function (subscriptions) {
      logger.debug({
        subscriptions: subscriptions
      }, 'polling each subscription');
      return _.map(subscriptions, throat(1, _.bind(function (subscription) {
        return this.pollSubscription(subscription);
      }, this)));
    })
    //poll subscription
    .then(function (pollPromises) {
      logger.info('settling all polls');
      return BBPromise.settle(pollPromises).cancellable();
    })
    .then(function () {
      //loop
      /* istanbul ignore else */
      if (this.running) {
        logger.info('pausing');
        return BBPromise.delay(1000)
          .cancellable()
          .bind(this)
          .then(function () {
            logger.info('looping');
            return this.poll();
          });
      } else {
        logger.info('poller stopped so stopping');
      }
    }).catch(function (err) {
      logger.error(err, 'error during poll loop');
    });

};
PollerService.prototype.loadSubscriptions = function () {
  var query = Subscription.findOneAndUpdate({
      $and: [{
        $or: [{
          active: false
        }, {
          active: {
            $exists: false
          }
        }]
      }, {
        $or: [{
          nextPoll: {
            $lt: moment().utc().toDate()
          }
        }, {
          nextPoll: {
            $exists: false
          }
        }]
      }]
    }, {
      $set: {
        active: true
      }
    })
    .populate('application');
  return BBPromise.resolve(query.exec()).then(function (result) {
    return [].concat(result);
  });
};
PollerService.prototype.pollSubscription = function (subscription) {
  logger.info({
    subscription: subscription._id,
    application: subscription.application._id
  }, 'polling subscription');
  return BBPromise.try(function () {
      //wrap subscription
      var context = {
        subscription: new SubscriptionWrapper(subscription),
        application: subscription.application
      };

      return context;
    }, [], this)
    .bind(this)
    .then(function buildContext(context) {
      return ConnectorSetting.findOneAsync({
        key: context.subscription._subscription.connector,
        application: context.application._id,
        environment: 'live'
      }).then(function (connectorSettings) {
        context.connectorSettings = connectorSettings;
        return context;
      });
    })
    .then(function (context) {
      logger.debug({
        context: context
      }, 'setting context');
      //load buckets
      //load bouncer tokens based on buckets
      var query = {
        application: context.application._id,
        environment: 'live'
      };
      //load only buckets with authTokens attached
      query['meta.authToken.' + context.connectorSettings.key] = {
        $exists: true
      };
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'finding all auth buckets');
      return Bucket.findAsync(query)
        .then(function (buckets) {
          logger.debug({
            buckets: buckets
          }, 'found buckets');
          context.buckets = buckets;
          return context;
        });
    }).then(function (context) {
      //for each bouncer token
      //poll subscription
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'polling all buckets');
      var polls = _.map(context.buckets, throat(4, _.bind(function (bucket) {
        this.pollContext(context, bucket);
      }, this)));
      polls.push(this.pollContext(context));
      return [polls, context];
    }).spread(function (polls, context) {
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'settling root poll calls');
      //also poll without a bucket for private connections
      return BBPromise.settle(polls).then(function () {
        return context;
      });
    }).then(function (context) {
      //save changes to subscription
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'saving updates to subscription');
      context.subscription._subscription.active = false;
      return context.subscription.save();
    });
};

PollerService.prototype.pollContext = function (context, bucket) {
  logger.debug({
    context: context
  }, 'polling context');
  return BBPromise.try(function () {
      /* istanbul ignore else */
      if (bucket) {
        return BouncerToken.findOneAsync({
          _id: bucket.meta.authToken[context.connectorSettings.key]
        });
      }
    }, [], this)
    .bind(this)
    .then(function (bouncerToken) {
      var connectorsPath = path.resolve(config.get('Hoist.connectors.path'));
      var pollerPath = path.join(connectorsPath, context.connectorSettings.connectorType, config.get('Hoist.connectors.currentDirectoryName'), 'lib/poll.js');
      pollerPath = fs.realpathSync(pollerPath);
      logger.debug({
        path: pollerPath
      }, 'loading poller');

      var pollerMethod = require(pollerPath);
      var pollContext = {
        settings: context.connectorSettings.settings,
        connectorKey: context.connectorSettings.key,
        subscription: context.subscription,
        application: context.application.toObject()
      };
      if (bouncerToken) {
        pollContext.authorization = new Authorization(bouncerToken);
      }
      if (bucket) {
        pollContext.bucket = bucket.toObject();
      }
      logger.info({
        application: pollContext.application._id
      }, 'calling poll');
      return pollerMethod(pollContext, _.bind(function (eventName, payload) {
        return this.raiseEvent(pollContext, eventName, payload);
      }, this)).then(function () {
        logger.info({
          application: pollContext.application._id
        }, 'poll done');
      });
    });
};
PollerService.prototype.raiseEvent = function (context, eventName, payload) {
  var eventPipeline = new EventPipeline(HoistContext, model);
  logger.debug({
    context: context,
    eventName: eventName,
    payload: payload
  }, 'raising event');
  logger.info({
    eventName: eventName,
    application: context.application._id
  }, 'raising event');
  HoistContext.get()
    .then(function (hoistContext) {
      hoistContext.application = context.application;
      hoistContext.bucket = context.bucket;
      hoistContext.environment = 'live';
    }).then(function () {
      eventPipeline.raise(eventName, payload);
    });
};

module.exports = PollerService;
<commit_msg>move through all subscriptions before polling the same one again<commit_after>'use strict';
var _ = require('lodash');
var BBPromise = require('bluebird');
var model = require('hoist-model');
var Subscription = model.Subscription;
var Bucket = model.Bucket;
var BouncerToken = model.BouncerToken;
var ConnectorSetting = model.ConnectorSetting;
var SubscriptionWrapper = require('./subscription_wrapper');
var logger = require('hoist-logger');
var fs = require('fs');
var config = require('config');
var path = require('path');
var Authorization = require('hoist-connector-pipeline/lib/authorization');
var HoistContext = require('hoist-context');
var EventPipeline = require('hoist-events-pipeline');
var throat = require('throat')(BBPromise);
var moment = require('moment');

function PollerService() {

}

PollerService.prototype.start = function () {
  logger.info('starting poller service');
  //mark as running
  this.running = true;
  //start poll
  logger.info('starting loop');
  this.loop = this.poll().cancellable();
};
PollerService.prototype.stop = function () {
  return BBPromise.try(function () {
    logger.info('stopping poller service');
    //mark as stopped
    this.running = false;
    //cancel loop
    /* istanbul ignore else */
    if (this.loop) {
      if (this.loop.isCancellable()) {
        logger.info('cancelling loop');
        this.loop.cancel();
      } else {
        logger.warn('loop isn\'t cancellable for some reason');
      }
      //delete loop
      logger.info('deleting loop promise reference');
      delete this.loop;
    }
  }, [], this);

};
PollerService.prototype.poll = function () {
  //load subscriptions
  logger.info('loading subscriptions');
  return this.loadSubscriptions()
    .cancellable()
    .bind(this)
    //for each
    .then(function (subscriptions) {
      logger.debug({
        subscriptions: subscriptions
      }, 'polling each subscription');
      return _.map(subscriptions, throat(1, _.bind(function (subscription) {
        return this.pollSubscription(subscription);
      }, this)));
    })
    //poll subscription
    .then(function (pollPromises) {
      logger.info('settling all polls');
      return BBPromise.settle(pollPromises).cancellable();
    })
    .then(function () {
      //loop
      /* istanbul ignore else */
      if (this.running) {
        logger.info('pausing');
        return BBPromise.delay(1000)
          .cancellable()
          .bind(this)
          .then(function () {
            logger.info('looping');
            return this.poll();
          });
      } else {
        logger.info('poller stopped so stopping');
      }
    }).catch(function (err) {
      logger.error(err, 'error during poll loop');
    });

};
PollerService.prototype.loadSubscriptions = function () {
  this.polledSubscriptions = this.polledSubscriptions || [];
  var query = Subscription.findOneAndUpdate({
      $and: [{
        _id: {
          $nin: this.polledSubscriptions
        }
      }, {
        $or: [{
          active: false
        }, {
          active: {
            $exists: false
          }
        }]
      }, {
        $or: [{
          nextPoll: {
            $lt: moment().utc().toDate()
          }
        }, {
          nextPoll: {
            $exists: false
          }
        }]
      }]
    }, {
      $set: {
        active: true
      }
    })
    .populate('application');
  return BBPromise.resolve(query.exec()).bind(this).then(function (result) {
    if (!result) {
      this.polledSubscriptions = [];
    } else {
      this.polledSubscriptions.push(result._id);
    }
    return [].concat(result);
  });
};
PollerService.prototype.pollSubscription = function (subscription) {
  logger.info({
    subscription: subscription._id,
    application: subscription.application._id
  }, 'polling subscription');
  return BBPromise.try(function () {
      //wrap subscription
      var context = {
        subscription: new SubscriptionWrapper(subscription),
        application: subscription.application
      };

      return context;
    }, [], this)
    .bind(this)
    .then(function buildContext(context) {
      return ConnectorSetting.findOneAsync({
        key: context.subscription._subscription.connector,
        application: context.application._id,
        environment: 'live'
      }).then(function (connectorSettings) {
        context.connectorSettings = connectorSettings;
        return context;
      });
    })
    .then(function (context) {
      logger.debug({
        context: context
      }, 'setting context');
      //load buckets
      //load bouncer tokens based on buckets
      var query = {
        application: context.application._id,
        environment: 'live'
      };
      //load only buckets with authTokens attached
      query['meta.authToken.' + context.connectorSettings.key] = {
        $exists: true
      };
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'finding all auth buckets');
      return Bucket.findAsync(query)
        .then(function (buckets) {
          logger.debug({
            buckets: buckets
          }, 'found buckets');
          context.buckets = buckets;
          return context;
        });
    }).then(function (context) {
      //for each bouncer token
      //poll subscription
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'polling all buckets');
      var polls = _.map(context.buckets, throat(4, _.bind(function (bucket) {
        this.pollContext(context, bucket);
      }, this)));
      polls.push(this.pollContext(context));
      return [polls, context];
    }).spread(function (polls, context) {
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'settling root poll calls');
      //also poll without a bucket for private connections
      return BBPromise.settle(polls).then(function () {
        return context;
      });
    }).then(function (context) {
      //save changes to subscription
      logger.info({
        subscription: subscription._id,
        application: subscription.application._id
      }, 'saving updates to subscription');
      context.subscription._subscription.active = false;
      return context.subscription.save();
    });
};

PollerService.prototype.pollContext = function (context, bucket) {
  logger.debug({
    context: context
  }, 'polling context');
  return BBPromise.try(function () {
      /* istanbul ignore else */
      if (bucket) {
        return BouncerToken.findOneAsync({
          _id: bucket.meta.authToken[context.connectorSettings.key]
        });
      }
    }, [], this)
    .bind(this)
    .then(function (bouncerToken) {
      var connectorsPath = path.resolve(config.get('Hoist.connectors.path'));
      var pollerPath = path.join(connectorsPath, context.connectorSettings.connectorType, config.get('Hoist.connectors.currentDirectoryName'), 'lib/poll.js');
      pollerPath = fs.realpathSync(pollerPath);
      logger.debug({
        path: pollerPath
      }, 'loading poller');

      var pollerMethod = require(pollerPath);
      var pollContext = {
        settings: context.connectorSettings.settings,
        connectorKey: context.connectorSettings.key,
        subscription: context.subscription,
        application: context.application.toObject()
      };
      if (bouncerToken) {
        pollContext.authorization = new Authorization(bouncerToken);
      }
      if (bucket) {
        pollContext.bucket = bucket.toObject();
      }
      logger.info({
        application: pollContext.application._id
      }, 'calling poll');
      return pollerMethod(pollContext, _.bind(function (eventName, payload) {
        return this.raiseEvent(pollContext, eventName, payload);
      }, this)).then(function () {
        logger.info({
          application: pollContext.application._id
        }, 'poll done');
      });
    });
};
PollerService.prototype.raiseEvent = function (context, eventName, payload) {
  var eventPipeline = new EventPipeline(HoistContext, model);
  logger.debug({
    context: context,
    eventName: eventName,
    payload: payload
  }, 'raising event');
  logger.info({
    eventName: eventName,
    application: context.application._id
  }, 'raising event');
  HoistContext.get()
    .then(function (hoistContext) {
      hoistContext.application = context.application;
      hoistContext.bucket = context.bucket;
      hoistContext.environment = 'live';
    }).then(function () {
      eventPipeline.raise(eventName, payload);
    });
};

module.exports = PollerService;
<|endoftext|>


<commit_before>var map = L.map('map').setView([41.88, -87.63], 10);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
}).addTo(map);

var mapzen_key = "search-F2Xk0nk";
var url = 'https://search.mapzen.com/v1/autocomplete';
var inputElement = document.getElementsByTagName('input')[0];
var dataListEl = document.getElementsByTagName('datalist')[0];
var API_RATE_LIMIT = 1000;

/* TO-DO:
- Build out error handling
- Figure out workaround for datalist HTML only matching exactly
*/

/*
var autocomplete = throttle(function() {
  if (inputElement.value.length > 0) {
    var params = {
      api_key: mapzen_key,
      text: inputElement.value
    };
    callPelias(url, params);
  }
}, API_RATE_LIMIT);
*/

function callPelias(search_url, search_params) {
  AJAX.request(search_url, search_params, function (err, results) {
    if (err) {
      console.log(err);
    }
    if (results && results.features) {
      while (dataListEl.firstChild) {
        dataListEl.removeChild(dataListEl.firstChild);
      };
      if (results.features.length >= 5) {
        for (var i = 0; i < 5; ++i) {
          var option = document.createElement('option');
          option.value = results.features[i].properties.label;
          option.text = results.features[i].properties.label;
          dataListEl.appendChild(option);
        };
      }
      else {
        for (var i = 0; i < results.features.length; ++i) {
          var option = document.createElement('option');
          option.value = results.features[i].properties.label;
          option.text = results.features[i].properties.label;
          dataListEl.appendChild(option);
        };
      }
    }
  });
};

inputElement.addEventListener('keyup', throttle(function() {
  if (inputElement.value.length > 0) {
    var params = {
      api_key: mapzen_key,
      "focus.point.lon": -87.63,
      "focus.point.lat": 41.88,
      text: inputElement.value
    };
    console.log(inputElement.value);
    callPelias(url, params);

  }
}, API_RATE_LIMIT));

var pt = {
  "type": "Feature",
  "properties": {
    "marker-color": "#0f0"
  },
  "geometry": {
    "type": "Point",
    "coordinates": [-87.663906, 41.968421]
  }
};

$.ajax({
  dataType: "json",
  url: "chi-neighborhoods.geojson",
  success: function(data) {
    var chi_neighborhoods = data;

    for (var i = 0; i < chi_neighborhoods.features.length; ++i) {
      if (turf.inside(pt, chi_neighborhoods.features[i])) {
        console.log(chi_neighborhoods.features[i].properties.name);
        break;
      }
    };

    //L.geoJson(chi_neighborhoods).addTo(map);
  }
}).error(function() {});

var AJAX = {
  serialize: function (params) {
    var data = '';

    for (var key in params) {
      if (params.hasOwnProperty(key)) {
        var param = params[key];
        var type = param.toString();
        var value;

        if (data.length) {
          data += '&';
        }

        switch (type) {
          case '[object Array]':
          value = (param[0].toString() === '[object Object]') ? JSON.stringify(param) : param.join(',');
          break;
          case '[object Object]':
          value = JSON.stringify(param);
          break;
          case '[object Date]':
          value = param.valueOf();
          break;
          default:
          value = param;
          break;
        }

        data += encodeURIComponent(key) + '=' + encodeURIComponent(value);
      }
    }

    return data;
  },
  http_request: function (callback, context) {
    if (window.XDomainRequest) {
      return this.xdr(callback, context);
    } else {
      return this.xhr(callback, context);
    }
  },
  xhr: function (callback, context) {
    var xhr = new XMLHttpRequest();

    xhr.onerror = function (e) {
      xhr.onreadystatechange = L.Util.falseFn;
      var error = {
        code: xhr.status,
        message: xhr.statusText
      };

      callback.call(context, error, null);
    };

    xhr.onreadystatechange = function () {
      var response;
      var error;

      if (xhr.readyState === 4) {
        // Handle all non-200 responses first
        if (xhr.status !== 200) {
          error = {
            code: xhr.status,
            message: xhr.statusText
          };
          callback.call(context, error, null);
        } else {
          try {
            response = JSON.parse(xhr.responseText);
          } catch (e) {
            response = null;
            error = {
              code: 500,
              message: 'Parse Error'
            };
          }

          if (!error && response.error) {
            error = response.error;
            response = null;
          }

          xhr.onerror = L.Util.falseFn;

          callback.call(context, error, response);
        }
      }
    };

    return xhr;
  },
  xdr: function (callback, context) {
    var xdr = new window.XDomainRequest();

    xdr.onerror = function (e) {
      xdr.onload = L.Util.falseFn;

      // XDRs have no access to actual status codes
      var error = {
        code: 500,
        message: 'XMLHttpRequest Error'
      };
      callback.call(context, error, null);
    };

    // XDRs have .onload instead of .onreadystatechange
    xdr.onload = function () {
      var response;
      var error;

      try {
        response = JSON.parse(xdr.responseText);
      } catch (e) {
        response = null;
        error = {
          code: 500,
          message: 'Parse Error'
        };
      }

      if (!error && response.error) {
        error = response.error;
        response = null;
      }

      xdr.onerror = L.Util.falseFn;
      callback.call(context, error, response);
    };

    return xdr;
  },
  request: function (url, params, callback, context) {
    var paramString = this.serialize(params);
    var httpRequest = this.http_request(callback, context);

    httpRequest.open('GET', url + '?' + paramString);

    setTimeout(function () {
      httpRequest.send(null);
    }, 0);
  }
};

/*
* throttle Utility function (borrowed from underscore)
*/
function throttle (func, wait, options) {
  var context, args, result;
  var timeout = null;
  var previous = 0;
  if (!options) options = {};
  var later = function () {
    previous = options.leading === false ? 0 : new Date().getTime();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function () {
    var now = new Date().getTime();
    if (!previous && options.leading === false) previous = now;
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};
<commit_msg>added html5 geolocation back with check on neighborhoods<commit_after>var map = L.map('map').setView([41.88, -87.63], 10);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
}).addTo(map);

var mapzen_key = "search-F2Xk0nk";
var url = 'https://search.mapzen.com/v1/autocomplete';
var inputElement = document.getElementsByTagName('input')[0];
var dataListEl = document.getElementsByTagName('datalist')[0];
var API_RATE_LIMIT = 1000;

/* TO-DO:
- Build out error handling
- Figure out workaround for datalist HTML only matching exactly
- fix scoping so not everything is global
*/

/*
var autocomplete = throttle(function() {
  if (inputElement.value.length > 0) {
    var params = {
      api_key: mapzen_key,
      text: inputElement.value
    };
    callPelias(url, params);
  }
}, API_RATE_LIMIT);
*/

function callPelias(search_url, search_params) {
  AJAX.request(search_url, search_params, function (err, results) {
    if (err) {
      console.log(err);
    }
    if (results && results.features) {
      while (dataListEl.firstChild) {
        dataListEl.removeChild(dataListEl.firstChild);
      };
      if (results.features.length >= 5) {
        for (var i = 0; i < 5; ++i) {
          var option = document.createElement('option');
          option.value = results.features[i].properties.label;
          option.text = results.features[i].properties.label;
          dataListEl.appendChild(option);
        };
      }
      else {
        for (var i = 0; i < results.features.length; ++i) {
          var option = document.createElement('option');
          option.value = results.features[i].properties.label;
          option.text = results.features[i].properties.label;
          dataListEl.appendChild(option);
        };
      }
    }
  });
};

inputElement.addEventListener('keyup', throttle(function() {
  if (inputElement.value.length > 0) {
    var params = {
      api_key: mapzen_key,
      "focus.point.lon": -87.63,
      "focus.point.lat": 41.88,
      text: inputElement.value
    };
    console.log(inputElement.value);
    callPelias(url, params);

  }
}, API_RATE_LIMIT));

var coords = [];

function searchNeighborhoods(position, neighborhoods) {
  var pt = {
    "type": "Feature",
    "properties": {
      "marker-color": "#0f0"
    },
    "geometry": {
      "type": "Point",
      "coordinates": []
    }
  };

  pt["geometry"]["coordinates"] = [position.coords.longitude, position.coords.latitude];
  console.log("coordinates are " + pt["geometry"]["coordinates"]);

  for (var i = 0; i < neighborhoods.features.length; ++i) {
    if (turf.inside(pt, neighborhoods.features[i])) {
      console.log(chi_neighborhoods.features[i].properties.name);
      break;
    }
    else if (i == neighborhoods.features.length - 1) {
      console.log("outside Chicago");
    }
  };
};

$.ajax({
  dataType: "json",
  url: "chi-neighborhoods.geojson",
  success: function(data) {
    var chi_neighborhoods = data;
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        searchNeighborhoods(position, chi_neighborhoods);
      });
    }
    else {
      console.log("geolocation not supported");
    }
    //L.geoJson(chi_neighborhoods).addTo(map);
  }
}).error(function() {});

var AJAX = {
  serialize: function (params) {
    var data = '';

    for (var key in params) {
      if (params.hasOwnProperty(key)) {
        var param = params[key];
        var type = param.toString();
        var value;

        if (data.length) {
          data += '&';
        }

        switch (type) {
          case '[object Array]':
          value = (param[0].toString() === '[object Object]') ? JSON.stringify(param) : param.join(',');
          break;
          case '[object Object]':
          value = JSON.stringify(param);
          break;
          case '[object Date]':
          value = param.valueOf();
          break;
          default:
          value = param;
          break;
        }

        data += encodeURIComponent(key) + '=' + encodeURIComponent(value);
      }
    }

    return data;
  },
  http_request: function (callback, context) {
    if (window.XDomainRequest) {
      return this.xdr(callback, context);
    } else {
      return this.xhr(callback, context);
    }
  },
  xhr: function (callback, context) {
    var xhr = new XMLHttpRequest();

    xhr.onerror = function (e) {
      xhr.onreadystatechange = L.Util.falseFn;
      var error = {
        code: xhr.status,
        message: xhr.statusText
      };

      callback.call(context, error, null);
    };

    xhr.onreadystatechange = function () {
      var response;
      var error;

      if (xhr.readyState === 4) {
        // Handle all non-200 responses first
        if (xhr.status !== 200) {
          error = {
            code: xhr.status,
            message: xhr.statusText
          };
          callback.call(context, error, null);
        } else {
          try {
            response = JSON.parse(xhr.responseText);
          } catch (e) {
            response = null;
            error = {
              code: 500,
              message: 'Parse Error'
            };
          }

          if (!error && response.error) {
            error = response.error;
            response = null;
          }

          xhr.onerror = L.Util.falseFn;

          callback.call(context, error, response);
        }
      }
    };

    return xhr;
  },
  xdr: function (callback, context) {
    var xdr = new window.XDomainRequest();

    xdr.onerror = function (e) {
      xdr.onload = L.Util.falseFn;

      // XDRs have no access to actual status codes
      var error = {
        code: 500,
        message: 'XMLHttpRequest Error'
      };
      callback.call(context, error, null);
    };

    // XDRs have .onload instead of .onreadystatechange
    xdr.onload = function () {
      var response;
      var error;

      try {
        response = JSON.parse(xdr.responseText);
      } catch (e) {
        response = null;
        error = {
          code: 500,
          message: 'Parse Error'
        };
      }

      if (!error && response.error) {
        error = response.error;
        response = null;
      }

      xdr.onerror = L.Util.falseFn;
      callback.call(context, error, response);
    };

    return xdr;
  },
  request: function (url, params, callback, context) {
    var paramString = this.serialize(params);
    var httpRequest = this.http_request(callback, context);

    httpRequest.open('GET', url + '?' + paramString);

    setTimeout(function () {
      httpRequest.send(null);
    }, 0);
  }
};

/*
* throttle Utility function (borrowed from underscore)
*/
function throttle (func, wait, options) {
  var context, args, result;
  var timeout = null;
  var previous = 0;
  if (!options) options = {};
  var later = function () {
    previous = options.leading === false ? 0 : new Date().getTime();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function () {
    var now = new Date().getTime();
    if (!previous && options.leading === false) previous = now;
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};
<|endoftext|>


<commit_before>module.exports = {
    "dev": {
        "accepted": "{0}不是{1}的可接受值, 请用下列之一的值:{2}",
        "deprecated": "{0}的方法已被移除, 请更新您的代码去使用{1}",
        "noChange": "{0}没有更新, 因为它并没有改变。",
        "noContainer": "无法在该页找到容器去匹配{0}",
        "of": "的",
        "oldStyle": "样式属性{0}现在已经直接嵌入到。{1}（）。",
        "sameEdge": "边缘不能链接到自己。自动去除自我参照边缘{0}。",
        "set": "{0}已经被设置。",
        "setLong": "{0}被设置为{1}。",
        "setContainer": "请使用()容器来定义div容器"
    },
    "error": {
        "accepted": "{0}对于{2}的可视化效果并不是一个可接受的{1}, 请使用如下的一个：{3}.",
        "connections": "没有对{0}可用的连接。",
        "data": "无可用数据",
        "dataYear": "没有数据对{0}可用。",
        "lib": "{0}的可视化要求装载{1}库。",
        "libs": "{0}的可视化需要加载以下库：{1}。",
        "method": "{0}的可视化要求设置{1}方法。",
        "methods": "{0}的可视化要求设置以下方法：{1}。"
    },
    "format": {
        decimal: ".",
        thousands: ",",
        grouping: [3],
        currency: ["¥", ""],
        dateTime: "%A %B %e %Y %X",
        date: "%Y/%-m/%-d",
        time: "%H:%M:%S",
        periods: ["上午", "下午"],
        days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
        shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
    },
    "lowercase": [
        "一个",
        "和",
        "在",
        "但是",
        "在...里",
        "的",
        "或者",
        "这",
        "向",
        "与...一起"
    ],
    "method": {
        "active": "活跃段",
        "color": "颜色",
        "depth": "深度",
        "dev": "详细",
        "focus": "焦点",
        "icon": "图标",
        "id": "身份认证",
        "height": "高度",
        "labels": "标签",
        "legend": "图例注释",
        "margin": "外边距",
        "messages": "状态消息",
        "order": "规则",
        "search": "搜索",
        "shape": "形状",
        "size": "大小",
        "style": "样式",
        "temp": "暂时性区段",
        "text": "文本",
        "time": "时间",
        "timeline": "时间轴",
        "total": "总段",
        "type": "类型",
        "width": "宽度",
        "x": "X轴",
        "y": "Y轴",
        "zoom": "缩放",
        "mode": "模式"
    },
    "time": [
        "日",
        "星期",
        "月",
        "时间",
        "年"
    ],
    "visualization": {
        "bar": "条形图",
        "box": "箱线图",
        "bubbles": "气泡",
        "chart": "图表",
        "geo_map": "地理地图",
        "line": "线图",
        "network": "网络",
        "path": "路径",
        "pie": "饼图",
        "rings": "特性",
        "scatter": "散点图",
        "stacked": "堆积面积图",
        "table": "表",
        "tree_map": "树图"
    },
    "ui": {
        "and": "和",
        "back": "后面",
        "collapse": "点击合并",
        "error": "错误",
        "expand": "单击以展开",
        "loading": "载入中...",
        "more": "{0}更多",
        "moreInfo": "点击了解更多信息",
        "noResults": "没有结果匹配{0}。",
        "or": "或",
        "primary": "主要连接",
        "share": "共享",
        "total": "总",
        "values": "值",
        "including": "包括"
    },
    "message": {
        "data": "分析数据",
        "draw": "绘制可视化",
        "initializing": "初始化{0}",
        "loading": "加载数据",
        "tooltipReset": "重置工具提示",
        "ui": "更新UI"
    },
    "uppercase": [
        "电视",
        "用户界面",
        "研发"
    ]
}
<commit_msg>updated zh_CN translations<commit_after>module.exports = {
    "format": {
        "decimal": ".",
        "thousands": ",",
        "grouping": [3],
        "currency": ["¥", ""],
        "dateTime": "%A %B %e %Y %X",
        "date": "%Y/%-m/%-d",
        "time": "%H:%M:%S",
        "periods": ["上午", "下午"],
        "days": ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        "shortDays": ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
        "shortMonths": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
    },
    "dev": {
        "accepted": "{0}不是{1}的可接受值, 请用下列之一的值:{2}",
        "deprecated": "{0}的方法已被移除, 请更新您的代码去使用{1}",
        "noChange": "{0}没有更新, 因为它并没有改变。",
        "noContainer": "无法在该页找到容器去匹配{0}",
        "of": "的",
        "oldStyle": "样式属性{0}现在已经直接嵌入到。{1}（）。",
        "sameEdge": "边缘不能链接到自己。自动去除自我参照边缘{0}。",
        "set": "{0}已经被设置。",
        "setLong": "{0}被设置为{1}。",
        "setContainer": "请使用()容器来定义div容器"
    },
    "error": {
        "accepted": "{0}对于{2}的可视化效果并不是一个可接受的{1}, 请使用如下的一个：{3}.",
        "connections": "没有对{0}可用的连接。",
        "data": "无可用数据",
        "dataYear": "没有数据对{0}可用。",
        "lib": "{0}的可视化要求装载{1}库。",
        "libs": "{0}的可视化需要加载以下库：{1}。",
        "method": "{0}的可视化要求设置{1}方法。",
        "methods": "{0}的可视化要求设置以下方法：{1}。"
    },
    "lowercase": [
        "一个",
        "和",
        "在",
        "但是",
        "在...里",
        "的",
        "或者",
        "这",
        "向",
        "与...一起"
    ],
    "method": {
        "active": "活跃段",
        "color": "颜色",
        "depth": "深度",
        "dev": "详细",
        "focus": "焦点",
        "icon": "图标",
        "id": "身份认证",
        "height": "高度",
        "labels": "标签",
        "legend": "图例注释",
        "margin": "外边距",
        "messages": "状态消息",
        "order": "规则",
        "search": "搜索",
        "shape": "形状",
        "size": "大小",
        "style": "样式",
        "temp": "暂时性区段",
        "text": "文本",
        "time": "时间",
        "timeline": "时间轴",
        "total": "总段",
        "type": "类型",
        "width": "宽度",
        "x": "X轴",
        "y": "Y轴",
        "zoom": "缩放",
        "mode": "模式"
    },
    "time": [
        "日",
        "星期",
        "月",
        "时间",
        "年"
    ],
    "visualization": {
        "bubbles": "气泡",
        "chart": "图表",
        "geo_map": "地理地图",
        "line": "线图",
        "network": "网络",
        "rings": "特性",
        "scatter": "散点图",
        "stacked": "堆积面积图",
        "tree_map": "树图",
        "bar": "条图",
        "box": "箱线图",
        "paths": "路径",
        "pie": "饼图",
        "table": "表"
    },
    "ui": {
        "and": "和",
        "back": "后面",
        "collapse": "点击合并",
        "error": "错误",
        "expand": "单击以展开",
        "loading": "载入中...",
        "more": "{0}更多",
        "moreInfo": "点击了解更多信息",
        "noResults": "没有结果匹配{0}。",
        "primary": "主要连接",
        "share": "共享",
        "total": "总",
        "values": "值",
        "including": "包括",
        "or": "或"
    },
    "message": {
        "data": "分析数据",
        "draw": "绘制可视化",
        "initializing": "初始化{0}",
        "loading": "加载数据",
        "tooltipReset": "重置工具提示",
        "ui": "更新UI"
    },
    "uppercase": [
        "CEO",
        "CEOs",
        "CFO",
        "CFOs",
        "CNC",
        "COO",
        "COOs",
        "CPU",
        "CPUs",
        "GDP",
        "HVAC",
        "ID",
        "电视",
        "用户界面",
        "研发"
    ]
}
<|endoftext|>


<commit_before>'use strict';

angular
    .module('app')
    .controller('rgiActiveAnswerButtonsCtrl', function (
        $scope,
        $location,
        $rootScope,
        $routeParams,
        $route,
        rgiAnswerSrvc,
        rgiAnswerFilterSrvc,
        rgiAnswerMethodSrvc,
        rgiDialogFactory,
        rgiIdentitySrvc,
        rgiNotifier,
        rgiQuestionSetSrvc,
        rgiReferenceListSrvc,
        rgiUrlGuideSrvc,
        rgiUtilsSrvc
    ) {
        $scope.current_user = rgiIdentitySrvc.currentUser;

        var assessment_ID = $routeParams.answer_ID.substring(0, $routeParams.answer_ID.length - 4),
            _ = $scope.$parent.$parent._;

        var deactivateAssessmentWatcher = $rootScope.$watch(function() {
            return $scope.$parent.assessment;
        }, function(assessment) {
            if(assessment !== undefined) {
                rgiAnswerSrvc.query({assessment_ID: assessment_ID}, function (answers) {
                    rgiQuestionSetSrvc.setAnswers(rgiAnswerFilterSrvc.getAnswers(answers, assessment));
                });

                deactivateAssessmentWatcher();
            }
        });

        var isTrialAssessment = function() {
            return ['trial_started', 'trial_submitted'].indexOf($scope.$parent.assessment.status) !== -1;
        };

        var updateAnswer = function(answerData, status, notificationMessage) {
            answerData.status = status;

            rgiAnswerMethodSrvc.updateAnswer(answerData)
                .then(function () {
                    if (status!=='saved'){
                        if (rgiQuestionSetSrvc.isAnyQuestionRemaining($scope.current_user.role, true, answerData) && !isTrialAssessment()) {
                            $location.path( rgiUrlGuideSrvc.getAnswerUrl(answerData.assessment_ID,
                                rgiQuestionSetSrvc.getNextQuestionId($scope.current_user.role, true, answerData)) );
                        } else {
                            $location.path(rgiUrlGuideSrvc.getAssessmentUrl(answerData.assessment_ID));
                        }
                    }
                    rgiNotifier.notify(notificationMessage);
                }, function (reason) {
                    rgiNotifier.error(reason);
                });
        };

        $scope.answerSave = function () {
            var new_answer_data = $scope.answer,
                flag_check = rgiUtilsSrvc.flagCheck(new_answer_data.flags);

            if (new_answer_data.new_answer_selection) {
                new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
            }

            if (new_answer_data.status!=='flagged' && flag_check) {
                new_answer_data.status = 'flagged';
            } else if (new_answer_data.status==='flagged' && !flag_check) {
                new_answer_data.status = 'saved';
            } else if (new_answer_data.status==='assigned') {
                new_answer_data.status = 'saved';
            }

            new_answer_data[$scope.current_user.role + '_resolve_flag_required'] = false;
            updateAnswer(new_answer_data, 'saved', 'Answer saved');

            // rgiAnswerMethodSrvc.updateAnswer(new_answer_data)
            //     .then(function () {
            //         rgiNotifier.notify('Answer saved');
            //     }, function (reason) {
            //         rgiNotifier.notify(reason);
            //     });
        };
        $scope.answerSubmit = function () {
            // answer.question_ID.dependant
            var new_answer_data = $scope.answer,
                auth_match = _.some($scope.references, function (ref) {
                    return (ref.author._id === $scope.current_user._id && !ref.hidden);
                });

            if (!new_answer_data[$scope.current_user.role + '_score'] && !new_answer_data.new_answer_selection) {
                rgiNotifier.error('You must pick a score');
            } else if (!new_answer_data[$scope.current_user.role + '_justification'] && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide a justification');
            } else if (rgiReferenceListSrvc.isEmpty(new_answer_data.references, $scope.current_user) && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide at least one supporting reference!');
            } else if ($scope.current_user.role === 'reviewer' && (new_answer_data.researcher_score.value !== $scope.question.question_criteria[new_answer_data.new_answer_selection].value) && !auth_match && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide at least one supporting reference for disagreements!');
            } else {
                if (new_answer_data.new_answer_selection) {
                    new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
                }
                updateAnswer(new_answer_data, 'submitted', 'Answer submitted');
            }
        };

        $scope.answerResubmit = function () {
            var new_answer_data = $scope.answer;
            new_answer_data[$scope.current_user.role + '_resolve_flag_required'] = false;

            if (!new_answer_data[$scope.current_user.role + '_score'] && new_answer_data.new_answer_selection) {
                rgiNotifier.error('You must pick a score');
            } else if (!new_answer_data[$scope.current_user.role + '_justification'] && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide a justification');
            } else {
                if (new_answer_data.new_answer_selection) {
                    new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
                }
                updateAnswer(new_answer_data, 'resubmitted', 'Answer resubmitted');
            }
        };

        $scope.answerApprove = function () {
            var new_answer_data = $scope.answer;

            if ((new_answer_data.status !== 'approved') && (rgiUtilsSrvc.flagCheck(new_answer_data.flags) === true)) {
                rgiNotifier.error('You can only approve an answer when all flags have been dealt with!');
            } else {
                updateAnswer(new_answer_data, 'approved', 'Answer approved', $scope.$parent.assessment.status !== 'trial_submitted');
            }
        };
        //TODO fix
        $scope.answerClear = function () {
            $route.reload();
            //$scope.answer = angular.copy($scope.$parent.answer_start);
        };

        $scope.answerReturn = function () {
            $location.path(rgiUrlGuideSrvc.getAssessmentUrl($scope.answer.assessment_ID));
        };

        $scope.answerFlag = function () {
            rgiDialogFactory.flagCreate($scope);
        };

        $scope.externalAnswer = function () {
            rgiDialogFactory.answerExternalChoice($scope);
        };

        $scope.answerUnresolved = function() {
            var new_answer_data = $scope.answer;

            if (rgiUtilsSrvc.flagCheck(new_answer_data.flags) !== true) {
                rgiNotifier.error('Only mark flagged answers as unresolved!');
            } else {
                updateAnswer(new_answer_data, 'unresolved', 'Answer tagged as unresolved');
            }
        };
        // make final choice
        $scope.finalChoiceDialog = function () {
            rgiDialogFactory.answerFinalChoice($scope);
        };
    });
<commit_msg>fixed flag save not tagging status. closes #385<commit_after>'use strict';

angular
    .module('app')
    .controller('rgiActiveAnswerButtonsCtrl', function (
        $scope,
        $location,
        $rootScope,
        $routeParams,
        $route,
        rgiAnswerSrvc,
        rgiAnswerFilterSrvc,
        rgiAnswerMethodSrvc,
        rgiDialogFactory,
        rgiIdentitySrvc,
        rgiNotifier,
        rgiQuestionSetSrvc,
        rgiReferenceListSrvc,
        rgiUrlGuideSrvc,
        rgiUtilsSrvc
    ) {
        $scope.current_user = rgiIdentitySrvc.currentUser;

        var assessment_ID = $routeParams.answer_ID.substring(0, $routeParams.answer_ID.length - 4),
            _ = $scope.$parent.$parent._;

        var deactivateAssessmentWatcher = $rootScope.$watch(function() {
            return $scope.$parent.assessment;
        }, function(assessment) {
            if(assessment !== undefined) {
                rgiAnswerSrvc.query({assessment_ID: assessment_ID}, function (answers) {
                    rgiQuestionSetSrvc.setAnswers(rgiAnswerFilterSrvc.getAnswers(answers, assessment));
                });

                deactivateAssessmentWatcher();
            }
        });

        var isTrialAssessment = function() {
            return ['trial_started', 'trial_submitted'].indexOf($scope.$parent.assessment.status) !== -1;
        };

        var updateAnswer = function(answerData, status, notificationMessage) {
            answerData.status = status;

            rgiAnswerMethodSrvc.updateAnswer(answerData)
                .then(function () {
                    if (status!=='saved'){
                        if (rgiQuestionSetSrvc.isAnyQuestionRemaining($scope.current_user.role, true, answerData) && !isTrialAssessment()) {
                            $location.path( rgiUrlGuideSrvc.getAnswerUrl(answerData.assessment_ID,
                                rgiQuestionSetSrvc.getNextQuestionId($scope.current_user.role, true, answerData)) );
                        } else {
                            $location.path(rgiUrlGuideSrvc.getAssessmentUrl(answerData.assessment_ID));
                        }
                    }
                    rgiNotifier.notify(notificationMessage);
                }, function (reason) {
                    rgiNotifier.error(reason);
                });
        };

        $scope.answerSave = function () {
            var new_answer_data = $scope.answer,
                flag_check = rgiUtilsSrvc.flagCheck(new_answer_data.flags),
                status = new_answer_data.status;

            if (new_answer_data.new_answer_selection) {
                new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
            }

            if (status!=='flagged' && flag_check) {
                status = 'flagged';
            } else if (status==='flagged' && !flag_check) {
                status = 'saved';
            } else if (status==='assigned') {
                status = 'saved';
            }

            new_answer_data[$scope.current_user.role + '_resolve_flag_required'] = false;
            updateAnswer(new_answer_data, status, 'Answer saved');

            // rgiAnswerMethodSrvc.updateAnswer(new_answer_data)
            //     .then(function () {
            //         rgiNotifier.notify('Answer saved');
            //     }, function (reason) {
            //         rgiNotifier.notify(reason);
            //     });
        };
        $scope.answerSubmit = function () {
            // answer.question_ID.dependant
            var new_answer_data = $scope.answer,
                auth_match = _.some($scope.references, function (ref) {
                    return (ref.author._id === $scope.current_user._id && !ref.hidden);
                });

            if (!new_answer_data[$scope.current_user.role + '_score'] && !new_answer_data.new_answer_selection) {
                rgiNotifier.error('You must pick a score');
            } else if (!new_answer_data[$scope.current_user.role + '_justification'] && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide a justification');
            } else if (rgiReferenceListSrvc.isEmpty(new_answer_data.references, $scope.current_user) && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide at least one supporting reference!');
            } else if ($scope.current_user.role === 'reviewer' && (new_answer_data.researcher_score.value !== $scope.question.question_criteria[new_answer_data.new_answer_selection].value) && !auth_match && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide at least one supporting reference for disagreements!');
            } else {
                if (new_answer_data.new_answer_selection) {
                    new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
                }
                updateAnswer(new_answer_data, 'submitted', 'Answer submitted');
            }
        };

        $scope.answerResubmit = function () {
            var new_answer_data = $scope.answer;
            new_answer_data[$scope.current_user.role + '_resolve_flag_required'] = false;

            if (!new_answer_data[$scope.current_user.role + '_score'] && new_answer_data.new_answer_selection) {
                rgiNotifier.error('You must pick a score');
            } else if (!new_answer_data[$scope.current_user.role + '_justification'] && !new_answer_data.question_ID.dependant) {
                rgiNotifier.error('You must provide a justification');
            } else {
                if (new_answer_data.new_answer_selection) {
                    new_answer_data[$scope.current_user.role + '_score'] = $scope.question.question_criteria[new_answer_data.new_answer_selection];
                }
                updateAnswer(new_answer_data, 'resubmitted', 'Answer resubmitted');
            }
        };

        $scope.answerApprove = function () {
            var new_answer_data = $scope.answer;

            if ((new_answer_data.status !== 'approved') && (rgiUtilsSrvc.flagCheck(new_answer_data.flags) === true)) {
                rgiNotifier.error('You can only approve an answer when all flags have been dealt with!');
            } else {
                updateAnswer(new_answer_data, 'approved', 'Answer approved', $scope.$parent.assessment.status !== 'trial_submitted');
            }
        };
        //TODO fix
        $scope.answerClear = function () {
            $route.reload();
            //$scope.answer = angular.copy($scope.$parent.answer_start);
        };

        $scope.answerReturn = function () {
            $location.path(rgiUrlGuideSrvc.getAssessmentUrl($scope.answer.assessment_ID));
        };

        $scope.answerFlag = function () {
            rgiDialogFactory.flagCreate($scope);
        };

        $scope.externalAnswer = function () {
            rgiDialogFactory.answerExternalChoice($scope);
        };

        $scope.answerUnresolved = function() {
            var new_answer_data = $scope.answer;

            if (rgiUtilsSrvc.flagCheck(new_answer_data.flags) !== true) {
                rgiNotifier.error('Only mark flagged answers as unresolved!');
            } else {
                updateAnswer(new_answer_data, 'unresolved', 'Answer tagged as unresolved');
            }
        };
        // make final choice
        $scope.finalChoiceDialog = function () {
            rgiDialogFactory.answerFinalChoice($scope);
        };
    });
<|endoftext|>


<commit_before>'use babel';
import { Disposable, CompositeDisposable } from 'atom';
import MinimapCodeglanceElement from './minimap-codeglance-element.js';

// private

// the minimap service object
var minimapService;

// minimap plugin activation state
var active = false;

// subscriptions
var disposables;

// the codeglance element
var codeglanceView;

// create the codeglance view and return a
// disposable that destroys it on disposal
function createView() {
  codeglanceView = new MinimapCodeglanceElement();

  return new Disposable(function onDispose() {
    codeglanceView.destroy();
    codeglanceView = null;
  });
}

// activate codeglance for the new minimap
function onDidCreateMinimap(minimap) {
  var minimapView = atom.views.getView(minimap);
  var isDragging = false;

  var minimapDisposable = new CompositeDisposable(
    addEventListener(minimapView, 'mouseenter', function onMouseEnter() {
      codeglanceView.setMinimap(minimap);
    }),
    addEventListener(minimapView, 'mousemove', function onMouseMove({offsetX: x, offsetY: y}) {
      if(!isDragging) codeglanceView.showLinesAtOffset({x, y});
    }),
    addEventListener(minimapView, 'mouseleave', function onMouseLeave() {
      codeglanceView.hide();
    }),
    addEventListener(minimapView, 'mousedown', function onMouseDown() {
      isDragging = true;
      codeglanceView.hide();

      var mouseUpDisposable = addEventListener(document.body, 'mouseup', function onMouseUp() {
        isDragging = false;
        mouseUpDisposable.dispose();
        mouseUpDisposable = null;
      });
    }),
    minimap.onDidDestroy(function onDestroyMinimap() {
      disposables.remove(minimapDisposable);
      minimapDisposable.dispose();
      minimapdisposable = null;
    })
  );

  disposables.add(minimapDisposable);
}

// return a disposable that removes the
// event handler on disposal
function addEventListener(el, event, cb) {
  el.addEventListener(event, cb);
  return new Disposable(function onDispose() {
    el.removeEventListener(event, cb);
  });
}

// public

var config = {
  numberOfLines: {
    type: 'integer',
    default: 5,
    minimum: 1,
    order: 1
  },
  showLineNumbers: {
    type: 'boolean',
    default: true,
    order: 2
  },
  codeHighlighting: {
    type: 'boolean',
    default: true,
    order: 3
  }
};
export { config };

export function activate() {}

export function deactivate() {
  deactivatePlugin();
  minimap.unregisterPlugin('codeglance');
  minimap = null;
}

export function consumeMinimapServiceV1(service) {
  minimapService = service;
  minimapService.registerPlugin('codeglance', MinimapCodeglance);
}

export function isActive() {
  return active;
}

export function activatePlugin() {
  if(active) return;
  active = true;

  disposables = new CompositeDisposable();
  disposables.add(
    createView(),
    minimapService.observeMinimaps(onDidCreateMinimap)
  );
}

export function deactivatePlugin() {
  if(!active) return;
  active = false;

  disposables.dispose();
  disposables = null;
}

var MinimapCodeglance;
export default MinimapCodeglance = { config, activate, deactivate, consumeMinimapServiceV1, isActive, activatePlugin, deactivatePlugin }
<commit_msg>fix some issues<commit_after>'use babel';
import { Disposable, CompositeDisposable } from 'atom';
import MinimapCodeglanceElement from './minimap-codeglance-element.js';

// private

// the minimap service object
var minimapService;

// minimap plugin activation state
var active = false;

// subscriptions
var disposables;

// the codeglance element
var codeglanceView;

// create the codeglance view and return a
// disposable that destroys it on disposal
function createView() {
  codeglanceView = new MinimapCodeglanceElement();

  return new Disposable(function onDispose() {
    codeglanceView.destroy();
    codeglanceView = null;
  });
}

// activate codeglance for the new minimap
function onDidCreateMinimap(minimap) {
  var minimapView = atom.views.getView(minimap);
  var isDragging = false;

  var minimapDisposable = new CompositeDisposable(
    addEventListener(minimapView, 'mouseenter', function onMouseEnter() {
      codeglanceView.setMinimap(minimap);
    }),
    addEventListener(minimapView, 'mousemove', function onMouseMove({offsetX: x, offsetY: y}) {
      if(!isDragging) codeglanceView.showLinesAtOffset({x, y});
    }),
    addEventListener(minimapView, 'mouseleave', function onMouseLeave() {
      codeglanceView.hide();
    }),
    addEventListener(minimapView, 'mousedown', function onMouseDown() {
      isDragging = true;
      codeglanceView.hide();

      var mouseUpDisposable = addEventListener(document.body, 'mouseup', function onMouseUp() {
        isDragging = false;
        mouseUpDisposable.dispose();
        mouseUpDisposable = null;
      });
    }),
    minimap.onDidDestroy(function onDestroyMinimap() {
      disposables.remove(minimapDisposable);
      minimapDisposable.dispose();
      minimapDisposable = null;
    })
  );

  disposables.add(minimapDisposable);
}

// return a disposable that removes the
// event handler on disposal
function addEventListener(el, event, cb) {
  el.addEventListener(event, cb);
  return new Disposable(function onDispose() {
    el.removeEventListener(event, cb);
  });
}

// public

var config = {
  numberOfLines: {
    type: 'integer',
    default: 5,
    minimum: 1,
    order: 1
  },
  showLineNumbers: {
    type: 'boolean',
    default: true,
    order: 2
  },
  codeHighlighting: {
    type: 'boolean',
    default: true,
    order: 3
  }
};
export { config };

export function activate() {}

export function deactivate() {
  deactivatePlugin();
  minimap.unregisterPlugin('codeglance');
  minimap = null;
}

export function consumeMinimapServiceV1(service) {
  minimapService = service;
  minimapService.registerPlugin('codeglance', MinimapCodeglance);
}

export function isActive() {
  return active;
}

export function activatePlugin() {
  if(active) return;
  active = true;

  disposables = new CompositeDisposable();
  disposables.add(
    createView(),
    minimapService.observeMinimaps(onDidCreateMinimap)
  );
}

export function deactivatePlugin() {
  if(!active) return;
  active = false;

  disposables.dispose();
  disposables = null;
}

var MinimapCodeglance;
export default MinimapCodeglance = { config, activate, deactivate, consumeMinimapServiceV1, isActive, activatePlugin, deactivatePlugin };
<|endoftext|>


<commit_before>import React from 'react';
import Title from 'react-title-component';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { Grid, Row, Col } from 'react-flexbox-grid/lib';
import MediaTable from '../MediaTable';
import { fetchTopicInfluentialMedia, sortTopicInfluentialMedia } from '../../../actions/topicActions';
import { DownloadButton } from '../../common/IconButton';
import messages from '../../../resources/messages';
import DataCard from '../../common/DataCard';
import composeAsyncContainer from '../../common/AsyncContainer';
import { pagedAndSortedLocation } from '../../util/location';
import composePagedContainer from '../../common/PagedContainer';
import MediaSourceIcon from '../../common/icons/MediaSourceIcon';

const localMessages = {
  title: { id: 'topic.influentialMedia.title', defaultMessage: 'Influential Media' },
};

class InfluentialMediaContainer extends React.Component {
  componentWillReceiveProps(nextProps) {
    const { fetchData, filters, sort, links } = this.props;
    if ((nextProps.filters.timespanId !== filters.timespanId) || (nextProps.sort !== sort) || (nextProps.links.current !== links.current)) {
      fetchData(nextProps);
    }
  }
  onChangeSort = (newSort) => {
    const { sortData } = this.props;
    sortData(newSort);
  }
  downloadCsv = () => {
    const { topicId, filters, sort } = this.props;
    const url = `/api/topics/${topicId}/media.csv?snapshotId=${filters.snapshotId}&timespanId=${filters.timespanId}&sort=${sort}`;
    window.location = url;
  }
  render() {
    const { media, sort, topicId, previousButton, nextButton } = this.props;
    const { formatMessage } = this.props.intl;
    const titleHandler = parentTitle => `${formatMessage(localMessages.title)} | ${parentTitle}`;
    return (
      <Grid>
        <Row>
          <Col lg={12} md={12} sm={12}>
            <Title render={titleHandler} />
            <DataCard border={false}>

                <DownloadButton tooltip={formatMessage(messages.download)} onClick={this.downloadCsv} />

                <MediaSourceIcon />
                <FormattedMessage {...localMessages.title} />

              <MediaTable media={media} topicId={topicId} onChangeSort={this.onChangeSort} sortedBy={sort} />
              { previousButton }
              { nextButton }
            </DataCard>
          </Col>
        </Row>
      </Grid>
    );
  }
}

InfluentialMediaContainer.ROWS_PER_PAGE = 50;

InfluentialMediaContainer.propTypes = {
  fetchStatus: React.PropTypes.string.isRequired,
  sort: React.PropTypes.string.isRequired,
  media: React.PropTypes.array.isRequired,
  topicId: React.PropTypes.number.isRequired,
  topicInfo: React.PropTypes.object.isRequired,
  fetchData: React.PropTypes.func.isRequired,
  sortData: React.PropTypes.func.isRequired,
  intl: React.PropTypes.object.isRequired,
  filters: React.PropTypes.object.isRequired,
  links: React.PropTypes.object,
  // from PagedContainer wrapper
  nextButton: React.PropTypes.node,
  previousButton: React.PropTypes.node,
};

const mapStateToProps = state => ({
  fetchStatus: state.topics.selected.media.fetchStatus,
  sort: state.topics.selected.media.sort,
  media: state.topics.selected.media.media,
  links: state.topics.selected.media.link_ids,
  filters: state.topics.selected.filters,
  topicId: state.topics.selected.id,
  topicInfo: state.topics.selected.info,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  fetchData: (props, linkId) => {
    const params = {
      ...props.filters,
      sort: props.sort,
      limit: InfluentialMediaContainer.ROWS_PER_PAGE,
      linkId,
    };
    dispatch(fetchTopicInfluentialMedia(props.topicId, params))
      .then((results) => {
        dispatch(push(pagedAndSortedLocation(ownProps.location, results.link_ids.current, props.sort)));
      });
  },
  sortData: (sort) => {
    dispatch(push(pagedAndSortedLocation(ownProps.location, null, sort)));
    dispatch(sortTopicInfluentialMedia(sort));
  },
});

function mergeProps(stateProps, dispatchProps, ownProps) {
  return Object.assign({}, stateProps, dispatchProps, ownProps, {
    asyncFetch: () => {
      dispatchProps.fetchData(stateProps);
    },
    nextPage: () => {
      dispatchProps.fetchData(stateProps, stateProps.links.next);
    },
    previousPage: () => {
      dispatchProps.fetchData(stateProps, stateProps.links.previous);
    },
  });
}

export default
  injectIntl(
    connect(mapStateToProps, mapDispatchToProps, mergeProps)(
      composePagedContainer(
        composeAsyncContainer(
          InfluentialMediaContainer
        )
      )
    )
  );
<commit_msg>size icon better<commit_after>import React from 'react';
import Title from 'react-title-component';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { Grid, Row, Col } from 'react-flexbox-grid/lib';
import MediaTable from '../MediaTable';
import { fetchTopicInfluentialMedia, sortTopicInfluentialMedia } from '../../../actions/topicActions';
import { DownloadButton } from '../../common/IconButton';
import messages from '../../../resources/messages';
import DataCard from '../../common/DataCard';
import composeAsyncContainer from '../../common/AsyncContainer';
import { pagedAndSortedLocation } from '../../util/location';
import composePagedContainer from '../../common/PagedContainer';
import MediaSourceIcon from '../../common/icons/MediaSourceIcon';

const localMessages = {
  title: { id: 'topic.influentialMedia.title', defaultMessage: 'Influential Media' },
};

class InfluentialMediaContainer extends React.Component {
  componentWillReceiveProps(nextProps) {
    const { fetchData, filters, sort, links } = this.props;
    if ((nextProps.filters.timespanId !== filters.timespanId) || (nextProps.sort !== sort) || (nextProps.links.current !== links.current)) {
      fetchData(nextProps);
    }
  }
  onChangeSort = (newSort) => {
    const { sortData } = this.props;
    sortData(newSort);
  }
  downloadCsv = () => {
    const { topicId, filters, sort } = this.props;
    const url = `/api/topics/${topicId}/media.csv?snapshotId=${filters.snapshotId}&timespanId=${filters.timespanId}&sort=${sort}`;
    window.location = url;
  }
  render() {
    const { media, sort, topicId, previousButton, nextButton } = this.props;
    const { formatMessage } = this.props.intl;
    const titleHandler = parentTitle => `${formatMessage(localMessages.title)} | ${parentTitle}`;
    return (
      <Grid>
        <Row>
          <Col lg={12} md={12} sm={12}>
            <Title render={titleHandler} />
            <DataCard border={false}>

                <DownloadButton tooltip={formatMessage(messages.download)} onClick={this.downloadCsv} />

                <MediaSourceIcon height={32} />
                <FormattedMessage {...localMessages.title} />

              <MediaTable media={media} topicId={topicId} onChangeSort={this.onChangeSort} sortedBy={sort} />
              { previousButton }
              { nextButton }
            </DataCard>
          </Col>
        </Row>
      </Grid>
    );
  }
}

InfluentialMediaContainer.ROWS_PER_PAGE = 50;

InfluentialMediaContainer.propTypes = {
  fetchStatus: React.PropTypes.string.isRequired,
  sort: React.PropTypes.string.isRequired,
  media: React.PropTypes.array.isRequired,
  topicId: React.PropTypes.number.isRequired,
  topicInfo: React.PropTypes.object.isRequired,
  fetchData: React.PropTypes.func.isRequired,
  sortData: React.PropTypes.func.isRequired,
  intl: React.PropTypes.object.isRequired,
  filters: React.PropTypes.object.isRequired,
  links: React.PropTypes.object,
  // from PagedContainer wrapper
  nextButton: React.PropTypes.node,
  previousButton: React.PropTypes.node,
};

const mapStateToProps = state => ({
  fetchStatus: state.topics.selected.media.fetchStatus,
  sort: state.topics.selected.media.sort,
  media: state.topics.selected.media.media,
  links: state.topics.selected.media.link_ids,
  filters: state.topics.selected.filters,
  topicId: state.topics.selected.id,
  topicInfo: state.topics.selected.info,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  fetchData: (props, linkId) => {
    const params = {
      ...props.filters,
      sort: props.sort,
      limit: InfluentialMediaContainer.ROWS_PER_PAGE,
      linkId,
    };
    dispatch(fetchTopicInfluentialMedia(props.topicId, params))
      .then((results) => {
        dispatch(push(pagedAndSortedLocation(
          ownProps.location,
          results.link_ids.current,
          props.sort,
          props.filters,
        )));
      });
  },
  sortData: (sort) => {
    dispatch(push(pagedAndSortedLocation(ownProps.location, null, sort)));
    dispatch(sortTopicInfluentialMedia(sort));
  },
});

function mergeProps(stateProps, dispatchProps, ownProps) {
  return Object.assign({}, stateProps, dispatchProps, ownProps, {
    asyncFetch: () => {
      dispatchProps.fetchData(stateProps);
    },
    nextPage: () => {
      dispatchProps.fetchData(stateProps, stateProps.links.next);
    },
    previousPage: () => {
      dispatchProps.fetchData(stateProps, stateProps.links.previous);
    },
  });
}

export default
  injectIntl(
    connect(mapStateToProps, mapDispatchToProps, mergeProps)(
      composePagedContainer(
        composeAsyncContainer(
          InfluentialMediaContainer
        )
      )
    )
  );
<|endoftext|>


<commit_before>
var fs = require('fs');

module.exports = Config;

function Config() {
    var self = this;

    self.fetchUserAgent = function() {
        var properties = self.getProperties();
        return properties.name + "-v" + properties.version;
    };

    self.getProperties = function() {
        return JSON.parse(fs.readFileSync('./package.json', 'utf8'));
    }
}<commit_msg>#191 Customize User Agent header. Jshint error fix<commit_after>
var fs = require('fs');

module.exports = Config;

function Config() {
    var self = this;

    self.fetchUserAgent = function() {
        var properties = self.getProperties();
        return properties.name + "-v" + properties.version;
    };

    self.getProperties = function() {
        return JSON.parse(fs.readFileSync('./package.json', 'utf8'));
    };
}<|endoftext|>