counter.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. var _ = require('underscore');
  2. var $ = require('jquery');
  3. var AppState = require('../app_state');
  4. var BaseView = require('./base');
  5. var CounterView = BaseView.extend({
  6. className: 'counter container-fluid',
  7. template: require('./counter.hbs'),
  8. initialize: function() {
  9. BaseView.prototype.initialize.apply(this, arguments);
  10. this.listenTo(AppState, 'change:graph_interval', this.render);
  11. this.start();
  12. },
  13. remove: function() {
  14. clearTimeout(this.poller);
  15. clearTimeout(this.animator);
  16. BaseView.prototype.remove.apply(this, arguments);
  17. },
  18. start: function() {
  19. this.poller = null;
  20. this.animator = null;
  21. this.delta = 0;
  22. this.looping = false;
  23. this.targetPollInterval = 10000;
  24. this.currentNum = -1;
  25. this.interval = 100;
  26. this.graphUrl = null;
  27. this.updateStats();
  28. },
  29. startLoop: function(i) {
  30. this.interval = i;
  31. this.poller = setTimeout(this.updateStats.bind(this), i);
  32. },
  33. updateStats: function() {
  34. $.get(AppState.apiPath('/counter')).done(function(data) {
  35. if (this.removed) {
  36. return;
  37. }
  38. var num = _.reduce(data['stats'], function(n, v) {
  39. return n + v['message_count'];
  40. }, 0);
  41. if (this.currentNum === -1) {
  42. // seed the display
  43. this.currentNum = num;
  44. this.writeCounts(this.currentNum);
  45. } else if (num > this.lastNum) {
  46. var delta = num - this.lastNum;
  47. this.delta = (delta / (this.interval / 1000)) / 50;
  48. if (!this.animator) {
  49. this.displayFrame();
  50. }
  51. }
  52. this.currentNum = this.lastNum;
  53. this.lastNum = num;
  54. var newInterval = this.interval;
  55. if (newInterval < this.targetPollInterval) {
  56. newInterval = this.interval + 1000;
  57. }
  58. this.startLoop(newInterval);
  59. $('#warning, #error').hide();
  60. if (data['message'] !== '') {
  61. $('#warning .alert').text(data['message']);
  62. $('#warning').show();
  63. }
  64. }.bind(this)).fail(function(jqXHR) {
  65. if (this.removed) {
  66. return;
  67. }
  68. clearTimeout(this.animator);
  69. this.animator = null;
  70. this.startLoop(10000);
  71. this.handleAJAXError(jqXHR);
  72. }.bind(this));
  73. if ($('#big_graph').length) {
  74. if (!this.graphUrl) {
  75. this.graphUrl = $('#big_graph').attr('src');
  76. }
  77. var uniq = Math.floor(Math.random() * 1000000);
  78. $('#big_graph').attr('src', this.graphUrl + '&_uniq=' + uniq);
  79. }
  80. },
  81. displayFrame: function() {
  82. this.currentNum += this.delta;
  83. this.writeCounts(this.currentNum);
  84. this.animator = setTimeout(this.displayFrame.bind(this), 1000 / 60);
  85. },
  86. writeCounts: function(c) {
  87. var text = parseInt(c, 10).toString();
  88. var node = $('.numbers')[0];
  89. var n = $('.numbers .number');
  90. for (var i = 0; i < text.length; i++) {
  91. var v = text.charAt(i);
  92. if (n.length > i) {
  93. var el = $(n[i]);
  94. el.show();
  95. el.find('.top').text(v);
  96. el.find('.bottom').text(v);
  97. } else {
  98. $(node).append('<span class="number"><span class="top">' + v +
  99. '</span><span class="bottom">' + v + '</span></span>\n');
  100. }
  101. }
  102. $('.numbers .number').each(function(ii, vv) {
  103. if (ii >= text.length) {
  104. $(vv).hide();
  105. }
  106. });
  107. }
  108. });
  109. module.exports = CounterView;