Commit | Line | Data |
---|---|---|
50ac472f | 1 | _kiwi.view.Channel = _kiwi.view.Panel.extend({ |
9b807765 | 2 | events: function(){ |
c794b877 | 3 | var parent_events = this.constructor.__super__.events; |
3499d625 | 4 | |
9b807765 D |
5 | if(_.isFunction(parent_events)){ |
6 | parent_events = parent_events(); | |
7 | } | |
8 | return _.extend({}, parent_events, { | |
3499d625 D |
9 | 'click .msg .nick' : 'nickClick', |
10 | "click .chan": "chanClick", | |
11 | 'click .media .open': 'mediaClick', | |
12 | 'mouseenter .msg .nick': 'msgEnter', | |
13 | 'mouseleave .msg .nick': 'msgLeave' | |
9b807765 | 14 | }); |
dfb5209c JA |
15 | }, |
16 | ||
50ac472f D |
17 | initialize: function (options) { |
18 | this.initializePanel(options); | |
c794b877 D |
19 | |
20 | // Container for all the messages | |
21 | this.$messages = $('<div class="messages"></div>'); | |
22 | this.$el.append(this.$messages); | |
23 | ||
50ac472f D |
24 | this.model.bind('change:topic', this.topic, this); |
25 | ||
7d2a2771 D |
26 | if (this.model.get('members')) { |
27 | this.model.get('members').bind('add', function (member) { | |
28 | if (member.get('nick') === this.model.collection.network.get('nick')) { | |
29 | this.$el.find('.initial_loader').slideUp(function () { | |
30 | $(this).remove(); | |
31 | }); | |
32 | } | |
33 | }, this); | |
34 | } | |
660e1427 | 35 | |
50ac472f D |
36 | // Only show the loader if this is a channel (ie. not a query) |
37 | if (this.model.isChannel()) { | |
247dd7ac | 38 | this.$el.append('<div class="initial_loader" style="margin:1em;text-align:center;"> ' + _kiwi.global.i18n.translate('client_views_channel_joining').fetch() + ' <span class="loader"></span></div>'); |
50ac472f | 39 | } |
c794b877 D |
40 | |
41 | this.model.bind('msg', this.newMsg, this); | |
42 | this.msg_count = 0; | |
50ac472f D |
43 | }, |
44 | ||
c794b877 | 45 | |
41a9c836 D |
46 | render: function () { |
47 | var that = this; | |
48 | ||
49 | this.$messages.empty(); | |
50 | _.each(this.model.get('scrollback'), function (msg) { | |
51 | that.newMsg(msg); | |
52 | }); | |
53 | }, | |
54 | ||
55 | ||
c794b877 D |
56 | newMsg: function (msg) { |
57 | var re, line_msg, | |
58 | nick_colour_hex, nick_hex, is_highlight, msg_css_classes = '', | |
59 | time_difference, | |
60 | sb = this.model.get('scrollback'), | |
425efe7a | 61 | prev_msg = sb[sb.length-2], |
e9c86682 | 62 | network, hour, pm; |
c794b877 D |
63 | |
64 | // Nick highlight detecting | |
65 | if ((new RegExp('(^|\\W)(' + escapeRegex(_kiwi.app.connections.active_connection.get('nick')) + ')(\\W|$)', 'i')).test(msg.msg)) { | |
66 | is_highlight = true; | |
67 | msg_css_classes += ' highlight'; | |
68 | } | |
69 | ||
70 | // Escape any HTML that may be in here | |
71 | msg.msg = $('<div />').text(msg.msg).html(); | |
72 | ||
73 | // Make the channels clickable | |
425efe7a | 74 | if ((network = this.model.get('network'))) { |
2910740d | 75 | re = new RegExp('(?:^|\\s)([' + escapeRegex(network.get('channel_prefix')) + '][^ ,\\007]+)', 'g'); |
425efe7a JA |
76 | msg.msg = msg.msg.replace(re, function (match) { |
77 | return '<a class="chan" data-channel="' + match.trim() + '">' + match + '</a>'; | |
78 | }); | |
79 | } | |
c794b877 D |
80 | |
81 | ||
82 | // Parse any links found | |
83 | msg.msg = msg.msg.replace(/(([A-Za-z][A-Za-z0-9\-]*\:\/\/)|(www\.))([\w.\-]+)([a-zA-Z]{2,6})(:[0-9]+)?(\/[\w#!:.?$'()[\]*,;~+=&%@!\-\/]*)?/gi, function (url) { | |
84 | var nice = url, | |
85 | extra_html = ''; | |
86 | ||
87 | // Add the http if no protoocol was found | |
88 | if (url.match(/^www\./)) { | |
89 | url = 'http://' + url; | |
90 | } | |
91 | ||
92 | // Shorten the displayed URL if it's going to be too long | |
93 | if (nice.length > 100) { | |
94 | nice = nice.substr(0, 100) + '...'; | |
95 | } | |
96 | ||
97 | // Get any media HTML if supported | |
98 | extra_html = _kiwi.view.MediaMessage.buildHtml(url); | |
99 | ||
100 | // Make the link clickable | |
101 | return '<a class="link_ext" target="_blank" rel="nofollow" href="' + url + '">' + nice + '</a>' + extra_html; | |
102 | }); | |
103 | ||
104 | ||
105 | // Convert IRC formatting into HTML formatting | |
106 | msg.msg = formatIRCMsg(msg.msg); | |
107 | ||
2eacc942 JA |
108 | // Replace text emoticons with images |
109 | if (_kiwi.global.settings.get('show_emoticons')) { | |
110 | msg.msg = emoticonFromText(msg.msg); | |
111 | } | |
c794b877 D |
112 | |
113 | // Add some colours to the nick (Method based on IRSSIs nickcolor.pl) | |
114 | nick_colour_hex = (function (nick) { | |
115 | var nick_int = 0, rgb; | |
116 | ||
117 | _.map(nick.split(''), function (i) { nick_int += i.charCodeAt(0); }); | |
118 | rgb = hsl2rgb(nick_int % 255, 70, 35); | |
119 | rgb = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16); | |
120 | ||
121 | return '#' + rgb.toString(16); | |
122 | })(msg.nick); | |
123 | ||
124 | msg.nick_style = 'color:' + nick_colour_hex + ';'; | |
125 | ||
126 | // Generate a hex string from the nick to be used as a CSS class name | |
127 | nick_hex = msg.nick_css_class = ''; | |
128 | if (msg.nick) { | |
129 | _.map(msg.nick.split(''), function (char) { | |
130 | nick_hex += char.charCodeAt(0).toString(16); | |
131 | }); | |
132 | msg_css_classes += ' nick_' + nick_hex; | |
133 | } | |
134 | ||
135 | if (prev_msg) { | |
136 | // Time difference between this message and the last (in minutes) | |
697a76c5 | 137 | time_difference = (msg.time.getTime() - prev_msg.time.getTime())/1000/60; |
c794b877 D |
138 | if (prev_msg.nick === msg.nick && time_difference < 1) { |
139 | msg_css_classes += ' repeated_nick'; | |
140 | } | |
141 | } | |
142 | ||
143 | // Build up and add the line | |
144 | msg.msg_css_classes = msg_css_classes; | |
62d1e896 JA |
145 | if (_kiwi.global.settings.get('use_24_hour_timestamps')) { |
146 | msg.time_string = msg.time.getHours().toString().lpad(2, "0") + ":" + msg.time.getMinutes().toString().lpad(2, "0") + ":" + msg.time.getSeconds().toString().lpad(2, "0"); | |
147 | } else { | |
148 | hour = msg.time.getHours(); | |
149 | pm = hour > 11; | |
36fb5f87 D |
150 | |
151 | hour = hour % 12; | |
152 | if (hour === 0) | |
153 | hour = 12; | |
154 | ||
62d1e896 JA |
155 | if (pm) { |
156 | msg.time_string = _kiwi.global.i18n.translate('client_views_panel_timestamp_pm').fetch(hour + ":" + msg.time.getMinutes().toString().lpad(2, "0") + ":" + msg.time.getSeconds().toString().lpad(2, "0")); | |
157 | } else { | |
158 | msg.time_string = _kiwi.global.i18n.translate('client_views_panel_timestamp_am').fetch(hour + ":" + msg.time.getMinutes().toString().lpad(2, "0") + ":" + msg.time.getSeconds().toString().lpad(2, "0")); | |
159 | } | |
160 | } | |
697a76c5 | 161 | line_msg = '<div class="msg <%= type %> <%= msg_css_classes %>"><div class="time"><%- time_string %></div><div class="nick" style="<%= nick_style %>"><%- nick %></div><div class="text" style="<%= style %>"><%= msg %> </div></div>'; |
c794b877 D |
162 | this.$messages.append(_.template(line_msg, msg)); |
163 | ||
164 | // Activity/alerts based on the type of new message | |
165 | if (msg.type.match(/^action /)) { | |
166 | this.alert('action'); | |
167 | ||
168 | } else if (is_highlight) { | |
169 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
170 | _kiwi.app.view.favicon.newHighlight(); | |
171 | _kiwi.app.view.playSound('highlight'); | |
ee2f0962 | 172 | _kiwi.app.view.showNotification(this.model.get('name'), msg.msg); |
c794b877 D |
173 | this.alert('highlight'); |
174 | ||
175 | } else { | |
176 | // If this is the active panel, send an alert out | |
177 | if (this.model.isActive()) { | |
178 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
179 | } | |
180 | this.alert('activity'); | |
181 | } | |
182 | ||
183 | if (this.model.isQuery() && !this.model.isActive()) { | |
184 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
ee2f0962 D |
185 | |
186 | // Highlights have already been dealt with above | |
c794b877 D |
187 | if (!is_highlight) { |
188 | _kiwi.app.view.favicon.newHighlight(); | |
189 | } | |
ee2f0962 D |
190 | |
191 | _kiwi.app.view.showNotification(this.model.get('name'), msg.msg); | |
c794b877 D |
192 | _kiwi.app.view.playSound('highlight'); |
193 | } | |
194 | ||
195 | // Update the activity counters | |
196 | (function () { | |
197 | // Only inrement the counters if we're not the active panel | |
198 | if (this.model.isActive()) return; | |
199 | ||
7ba064d9 D |
200 | var $act = this.model.tab.find('.activity'), |
201 | count_all_activity = _kiwi.global.settings.get('count_all_activity'), | |
202 | exclude_message_types; | |
203 | ||
204 | // Set the default config value | |
205 | if (typeof count_all_activity === 'undefined') { | |
206 | count_all_activity = false; | |
223d53e5 TL |
207 | } |
208 | ||
7ba064d9 D |
209 | // Do not increment the counter for these message types |
210 | exclude_message_types = [ | |
211 | 'action join', | |
212 | 'action quit', | |
213 | 'action part', | |
214 | 'action kick', | |
215 | 'action nick', | |
216 | 'action mode' | |
217 | ]; | |
218 | ||
a2094b47 | 219 | if (count_all_activity || _.indexOf(exclude_message_types, msg.type) === -1) { |
223d53e5 | 220 | $act.text((parseInt($act.text(), 10) || 0) + 1); |
223d53e5 TL |
221 | } |
222 | ||
c794b877 D |
223 | if ($act.text() === '0') { |
224 | $act.addClass('zero'); | |
225 | } else { | |
226 | $act.removeClass('zero'); | |
227 | } | |
228 | }).apply(this); | |
229 | ||
8c511395 | 230 | if(this.model.isActive()) this.scrollToBottom(); |
c794b877 D |
231 | |
232 | // Make sure our DOM isn't getting too large (Acts as scrollback) | |
233 | this.msg_count++; | |
234 | if (this.msg_count > (parseInt(_kiwi.global.settings.get('scrollback'), 10) || 250)) { | |
235 | $('.msg:first', this.$messages).remove(); | |
236 | this.msg_count--; | |
237 | } | |
50ac472f D |
238 | }, |
239 | ||
c794b877 | 240 | |
50ac472f D |
241 | topic: function (topic) { |
242 | if (typeof topic !== 'string' || !topic) { | |
243 | topic = this.model.get("topic"); | |
244 | } | |
245 | ||
530f55dc | 246 | this.model.addMsg('', styleText('client_views_channel_topic', {'%T': translateText('client_views_channel_topic', [this.model.get('name'), topic]), '%C': this.model.get('name')}), 'topic'); |
50ac472f D |
247 | |
248 | // If this is the active channel then update the topic bar | |
249 | if (_kiwi.app.panels().active === this) { | |
250 | _kiwi.app.topicbar.setCurrentTopic(this.model.get("topic")); | |
251 | } | |
dfb5209c JA |
252 | }, |
253 | ||
254 | // Click on a nickname | |
255 | nickClick: function (event) { | |
256 | var nick = $(event.currentTarget).text(), | |
257 | members = this.model.get('members'), | |
d62fa271 | 258 | are_we_an_op = !!members.getByNick(_kiwi.app.connections.active_connection.get('nick')).get('is_op'), |
dfb5209c JA |
259 | member, query, userbox, menubox; |
260 | ||
261 | if (members) { | |
262 | member = members.getByNick(nick); | |
263 | if (member) { | |
dfb5209c | 264 | userbox = new _kiwi.view.UserBox(); |
d62fa271 D |
265 | userbox.setTargets(member, this.model); |
266 | userbox.displayOpItems(are_we_an_op); | |
0826460d | 267 | |
dfb5209c JA |
268 | menubox = new _kiwi.view.MenuBox(member.get('nick') || 'User'); |
269 | menubox.addItem('userbox', userbox.$el); | |
279bf34b | 270 | menubox.showFooter(false); |
dfb5209c | 271 | menubox.show(); |
0826460d | 272 | |
dfb5209c JA |
273 | // Position the userbox + menubox |
274 | (function() { | |
275 | var t = event.pageY, | |
276 | m_bottom = t + menubox.$el.outerHeight(), // Where the bottom of menu will be | |
277 | memberlist_bottom = this.$el.parent().offset().top + this.$el.parent().outerHeight(); | |
278 | ||
279 | // If the bottom of the userbox is going to be too low.. raise it | |
280 | if (m_bottom > memberlist_bottom){ | |
281 | t = memberlist_bottom - menubox.$el.outerHeight(); | |
282 | } | |
283 | ||
284 | // Set the new positon | |
285 | menubox.$el.offset({ | |
286 | left: event.clientX, | |
287 | top: t | |
288 | }); | |
289 | }).call(this); | |
290 | } | |
291 | } | |
3499d625 D |
292 | }, |
293 | ||
294 | ||
295 | chanClick: function (event) { | |
425efe7a JA |
296 | var target = (event.target) ? $(event.target).data('channel') : $(event.srcElement).data('channel'); |
297 | ||
298 | _kiwi.app.connections.active_connection.gateway.join(target); | |
3499d625 D |
299 | }, |
300 | ||
301 | ||
302 | mediaClick: function (event) { | |
303 | var $media = $(event.target).parents('.media'); | |
304 | var media_message; | |
305 | ||
306 | if ($media.data('media')) { | |
307 | media_message = $media.data('media'); | |
308 | } else { | |
309 | media_message = new _kiwi.view.MediaMessage({el: $media[0]}); | |
310 | ||
311 | // Cache this MediaMessage instance for when it's opened again | |
312 | $media.data('media', media_message); | |
313 | } | |
314 | ||
315 | media_message.toggle(); | |
316 | }, | |
317 | ||
318 | ||
319 | // Cursor hovers over a message | |
320 | msgEnter: function (event) { | |
321 | var nick_class; | |
322 | ||
323 | // Find a valid class that this element has | |
324 | _.each($(event.currentTarget).parent('.msg').attr('class').split(' '), function (css_class) { | |
325 | if (css_class.match(/^nick_[a-z0-9]+/i)) { | |
326 | nick_class = css_class; | |
327 | } | |
328 | }); | |
329 | ||
330 | // If no class was found.. | |
331 | if (!nick_class) return; | |
332 | ||
333 | $('.'+nick_class).addClass('global_nick_highlight'); | |
334 | }, | |
335 | ||
336 | ||
337 | // Cursor leaves message | |
338 | msgLeave: function (event) { | |
339 | var nick_class; | |
340 | ||
341 | // Find a valid class that this element has | |
342 | _.each($(event.currentTarget).parent('.msg').attr('class').split(' '), function (css_class) { | |
343 | if (css_class.match(/^nick_[a-z0-9]+/i)) { | |
344 | nick_class = css_class; | |
345 | } | |
346 | }); | |
347 | ||
348 | // If no class was found.. | |
349 | if (!nick_class) return; | |
350 | ||
351 | $('.'+nick_class).removeClass('global_nick_highlight'); | |
352 | }, | |
dfb5209c | 353 | }); |