Merge branch 'text_themes' of https://github.com/CoryChaplin/KiwiIRC into CoryChaplin...
[KiwiIRC.git] / client / src / applets / chanlist.js
1 (function () {
2
3 var View = Backbone.View.extend({
4 events: {
5 "click .chan": "chanClick",
6 "click .channel_name_title": "sortChannelsByNameClick",
7 "click .users_title": "sortChannelsByUsersClick"
8 },
9
10
11
12 initialize: function (options) {
13 var text = {
14 channel_name: _kiwi.global.i18n.translate('client_applets_chanlist_channelname').fetch(),
15 users: _kiwi.global.i18n.translate('client_applets_chanlist_users').fetch(),
16 topic: _kiwi.global.i18n.translate('client_applets_chanlist_topic').fetch()
17 };
18 this.$el = $(_.template($('#tmpl_channel_list').html().trim(), text));
19
20 this.channels = [];
21
22 // Sort the table
23 this.order = '';
24
25 // Waiting to add the table back into the DOM?
26 this.waiting = false;
27 },
28
29 render: function () {
30 var table = $('table', this.$el),
31 tbody = table.children('tbody:first').detach(),
32 that = this,
33 i;
34
35 // Create the sort icon container and clean previous any previous ones
36 if($('.applet_chanlist .users_title').find('span.chanlist_sort_users').length == 0) {
37 this.$('.users_title').append('<span class="chanlist_sort_users">&nbsp;&nbsp;</span>');
38 } else {
39 this.$('.users_title span.chanlist_sort_users').removeClass('icon-sort-up');
40 this.$('.users_title span.chanlist_sort_users').removeClass('icon-sort-down');
41 }
42 if ($('.applet_chanlist .channel_name_title').find('span.chanlist_sort_names').length == 0) {
43 this.$('.channel_name_title').append('<span class="chanlist_sort_names">&nbsp;&nbsp;</span>');
44 } else {
45 this.$('.channel_name_title span.chanlist_sort_names').removeClass('icon-sort-up');
46 this.$('.channel_name_title span.chanlist_sort_names').removeClass('icon-sort-down');
47 }
48
49 // Push the new sort icon
50 switch (this.order) {
51 case 'user_desc':
52 default:
53 this.$('.users_title span.chanlist_sort_users').addClass('icon-sort-down');
54 break;
55 case 'user_asc':
56 this.$('.users_title span.chanlist_sort_users').addClass('icon-sort-up');
57 break;
58 case 'name_asc':
59 this.$('.channel_name_title span.chanlist_sort_names').addClass('icon-sort-up');
60 break;
61 case 'name_desc':
62 this.$('.channel_name_title span.chanlist_sort_names').addClass('icon-sort-down');
63 break;
64 }
65
66 this.channels = this.sortChannels(this.channels, this.order);
67
68 // Make sure all the channel DOM nodes are inserted in order
69 for (i = 0; i < this.channels.length; i++) {
70 tbody[0].appendChild(this.channels[i].dom);
71 }
72
73 table[0].appendChild(tbody[0]);
74 },
75
76
77 chanClick: function (event) {
78 if (event.target) {
79 _kiwi.gateway.join(null, $(event.target).data('channel'));
80 } else {
81 // IE...
82 _kiwi.gateway.join(null, $(event.srcElement).data('channel'));
83 }
84 },
85
86 sortChannelsByNameClick: function (event) {
87 // Revert the sorting to switch between orders
88 this.order = (this.order == 'name_asc') ? 'name_desc' : 'name_asc';
89
90 this.sortChannelsClick();
91 },
92
93 sortChannelsByUsersClick: function (event) {
94 // Revert the sorting to switch between orders
95 this.order = (this.order == 'user_desc' || this.order == '') ? 'user_asc' : 'user_desc';
96
97 this.sortChannelsClick();
98 },
99
100 sortChannelsClick: function() {
101 this.render();
102 },
103
104 sortChannels: function (channels, order) {
105 var sort_channels = [],
106 new_channels = [];
107
108
109 // First we create a light copy of the channels object to do the sorting
110 _.each(channels, function (chan, chan_idx) {
111 sort_channels.push({'chan_idx': chan_idx, 'num_users': chan.num_users, 'channel': chan.channel});
112 });
113
114 // Second, we apply the sorting
115 sort_channels.sort(function (a, b) {
116 switch (order) {
117 case 'user_asc':
118 return a.num_users - b.num_users;
119 case 'user_desc':
120 return b.num_users - a.num_users;
121 case 'name_asc':
122 if (a.channel.toLowerCase() > b.channel.toLowerCase()) return 1;
123 if (a.channel.toLowerCase() < b.channel.toLowerCase()) return -1;
124 case 'name_desc':
125 if (a.channel.toLowerCase() < b.channel.toLowerCase()) return 1;
126 if (a.channel.toLowerCase() > b.channel.toLowerCase()) return -1;
127 default:
128 return b.num_users - a.num_users;
129 }
130 return 0;
131 });
132
133 // Third, we re-shuffle the chanlist according to the sort order
134 _.each(sort_channels, function (chan) {
135 new_channels.push(channels[chan.chan_idx]);
136 });
137
138 return new_channels;
139 }
140 });
141
142
143
144 var Applet = Backbone.Model.extend({
145 initialize: function () {
146 this.set('title', _kiwi.global.i18n.translate('client_applets_chanlist_channellist').fetch());
147 this.view = new View();
148
149 this.network = _kiwi.global.components.Network();
150 this.network.on('onlist_channel', this.onListChannel, this);
151 this.network.on('onlist_start', this.onListStart, this);
152 },
153
154
155 // New channels to add to our list
156 onListChannel: function (event) {
157 this.addChannel(event.chans);
158 },
159
160 // A new, fresh channel list starting
161 onListStart: function (event) {
162 // TODO: clear out our existing list
163 },
164
165 addChannel: function (channels) {
166 var that = this;
167
168 if (!_.isArray(channels)) {
169 channels = [channels];
170 }
171 _.each(channels, function (chan) {
172 var row;
173 row = document.createElement("tr");
174 row.innerHTML = '<td class="chanlist_name"><a class="chan" data-channel="' + chan.channel + '">' + _.escape(chan.channel) + '</a></td><td class="chanlist_num_users" style="text-align: center;">' + chan.num_users + '</td><td style="padding-left: 2em;" class="chanlist_topic">' + formatIRCMsg(_.escape(chan.topic)) + '</td>';
175 chan.dom = row;
176 that.view.channels.push(chan);
177 });
178
179 if (!that.view.waiting) {
180 that.view.waiting = true;
181 _.defer(function () {
182 that.view.render();
183 that.view.waiting = false;
184 });
185 }
186 },
187
188
189 dispose: function () {
190 this.view.channels = null;
191 this.view.unbind();
192 this.view.$el.html('');
193 this.view.remove();
194 this.view = null;
195
196 // Remove any network event bindings
197 this.network.off();
198 }
199 });
200
201
202
203 _kiwi.model.Applet.register('kiwi_chanlist', Applet);
204 })();