Gitter migration: Point people to app.gitter.im (rollout pt. 1)
[gitter.git] / public / js / views / modals / people-modal.js
blobdd56ebc90cfc3ac75e5ce926e13105623c6493e7
1 'use strict';
3 var Marionette = require('backbone.marionette');
4 var Backbone = require('backbone');
5 var _ = require('lodash');
6 var ModalView = require('./modal');
7 var itemTemplate = require('./tmpl/people-modal-result.hbs');
8 var apiClient = require('../../components/api-client');
9 var template = require('./tmpl/people-modal.hbs');
10 var SyncMixin = require('../../collections/sync-mixin');
11 var InfiniteScrollBehavior = require('../behaviors/infinite-scroll');
12 var context = require('gitter-web-client-context');
14 require('../behaviors/widgets');
16 var RESULT_LIMIT = 25;
18 var UserCollection = Backbone.Collection.extend({
19   searchTerm: '',
20   isFetched: false,
21   limit: RESULT_LIMIT,
22   url: apiClient.room.channelGenerator('/users'),
23   sync: SyncMixin.sync,
24   fetchMoreBefore: function() {},
25   fetchMoreAfter: function() {
26     // already fetching or no more results to fetch
27     if (this.limit > this.length) return;
29     this.limit = this.limit + 25;
31     this.fetchWithLimit();
32   },
33   search: function(term) {
34     this.searchTerm = term || '';
35     // reset result limit for new search
36     this.limit = RESULT_LIMIT;
38     this.fetchWithLimit();
39   },
40   fetchWithLimit: function() {
41     var self = this;
43     var data = { limit: this.limit };
44     if (this.searchTerm) {
45       data.q = this.searchTerm;
46     }
48     this.fetch({
49       data: data,
50       success: function() {
51         self.isFetched = true;
52       }
53     });
54   }
55 });
57 var UserView = Marionette.ItemView.extend({
58   tagName: 'li',
59   className: 'people-modal-result',
60   template: itemTemplate,
61   modelEvents: {
62     change: 'render'
63   },
64   behaviors: {
65     Widgets: {}
66   }
67 });
69 var EmptyView = Marionette.ItemView.extend({
70   className: 'people-modal-empty',
71   serializeData: function() {
72     return { isFetched: this.collection.isFetched };
73   },
74   template: function(data) {
75     // wait until results come back to give negative feedback
76     return data.isFetched ? '<h3>Nope, nothing :(</h3>' : '';
77   }
78 });
80 var View = Marionette.CompositeView.extend({
81   className: 'people-modal',
82   template: template,
83   ui: {
84     search: 'input',
85     clear: '.js-people-modal-search-clear',
86     results: 'ul'
87   },
88   childViewContainer: '@ui.results',
89   childView: UserView,
90   emptyView: EmptyView,
91   events: {
92     'input @ui.search': 'onSearchInput',
93     'click @ui.clear': 'clearSearch'
94   },
95   reorderOnSort: true,
96   initialize: function() {
97     var self = this;
99     this.debouncedSearch = _.debounce(function() {
100       var term = self.ui.search.val();
101       self.collection.search(term);
102     }, 250);
104     this.once(
105       'render',
106       function() {
107         new InfiniteScrollBehavior({ scrollElement: this.ui.results[0] }, this);
108       },
109       this
110     );
111   },
112   emptyViewOptions: function() {
113     return { collection: this.collection };
114   },
115   onSearchInput: function() {
116     if (this.ui.search.val()) {
117       this.ui.clear.show();
118     } else {
119       this.ui.clear.hide();
120     }
122     this.debouncedSearch();
123   },
124   clearSearch: function() {
125     this.ui.search.val('');
126     this.collection.search('');
127     this.ui.clear.hide();
128   }
131 var Modal = ModalView.extend({
132   initialize: function(options) {
133     options = options || {};
134     options.title = 'People';
136     var room = context.troupe();
138     var users = new UserCollection(options.rosterCollection.models);
139     users.fetchWithLimit();
140     // make the user collection seem live
141     users.listenTo(room, 'change:userCount', users.fetchWithLimit);
143     ModalView.prototype.initialize.call(this, options);
144     this.view = new View({ collection: users });
145   }
148 module.exports = Modal;