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 JA |
61 | prev_msg = sb[sb.length-2], |
62 | network; | |
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 JA |
74 | if ((network = this.model.get('network'))) { |
75 | re = new RegExp('(?:^|\\s)([' + escapeRegex(network.get('channel_prefix')) + '][^ ,\\007]+)', 'g'); | |
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; | |
697a76c5 JA |
145 | msg.time_string = msg.time.getHours().toString().lpad(2, "0") + ":" + msg.time.getMinutes().toString().lpad(2, "0") + ":" + msg.time.getSeconds().toString().lpad(2, "0"); |
146 | 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 |
147 | this.$messages.append(_.template(line_msg, msg)); |
148 | ||
149 | // Activity/alerts based on the type of new message | |
150 | if (msg.type.match(/^action /)) { | |
151 | this.alert('action'); | |
152 | ||
153 | } else if (is_highlight) { | |
154 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
155 | _kiwi.app.view.favicon.newHighlight(); | |
156 | _kiwi.app.view.playSound('highlight'); | |
ee2f0962 | 157 | _kiwi.app.view.showNotification(this.model.get('name'), msg.msg); |
c794b877 D |
158 | this.alert('highlight'); |
159 | ||
160 | } else { | |
161 | // If this is the active panel, send an alert out | |
162 | if (this.model.isActive()) { | |
163 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
164 | } | |
165 | this.alert('activity'); | |
166 | } | |
167 | ||
168 | if (this.model.isQuery() && !this.model.isActive()) { | |
169 | _kiwi.app.view.alertWindow('* ' + _kiwi.global.i18n.translate('client_views_panel_activity').fetch()); | |
ee2f0962 D |
170 | |
171 | // Highlights have already been dealt with above | |
c794b877 D |
172 | if (!is_highlight) { |
173 | _kiwi.app.view.favicon.newHighlight(); | |
174 | } | |
ee2f0962 D |
175 | |
176 | _kiwi.app.view.showNotification(this.model.get('name'), msg.msg); | |
c794b877 D |
177 | _kiwi.app.view.playSound('highlight'); |
178 | } | |
179 | ||
180 | // Update the activity counters | |
181 | (function () { | |
182 | // Only inrement the counters if we're not the active panel | |
183 | if (this.model.isActive()) return; | |
184 | ||
7ba064d9 D |
185 | var $act = this.model.tab.find('.activity'), |
186 | count_all_activity = _kiwi.global.settings.get('count_all_activity'), | |
187 | exclude_message_types; | |
188 | ||
189 | // Set the default config value | |
190 | if (typeof count_all_activity === 'undefined') { | |
191 | count_all_activity = false; | |
223d53e5 TL |
192 | } |
193 | ||
7ba064d9 D |
194 | // Do not increment the counter for these message types |
195 | exclude_message_types = [ | |
196 | 'action join', | |
197 | 'action quit', | |
198 | 'action part', | |
199 | 'action kick', | |
200 | 'action nick', | |
201 | 'action mode' | |
202 | ]; | |
203 | ||
204 | if (count_all_activity || exclude_message_types.indexOf(msg.type) === -1) { | |
223d53e5 | 205 | $act.text((parseInt($act.text(), 10) || 0) + 1); |
223d53e5 TL |
206 | } |
207 | ||
c794b877 D |
208 | if ($act.text() === '0') { |
209 | $act.addClass('zero'); | |
210 | } else { | |
211 | $act.removeClass('zero'); | |
212 | } | |
213 | }).apply(this); | |
214 | ||
8c511395 | 215 | if(this.model.isActive()) this.scrollToBottom(); |
c794b877 D |
216 | |
217 | // Make sure our DOM isn't getting too large (Acts as scrollback) | |
218 | this.msg_count++; | |
219 | if (this.msg_count > (parseInt(_kiwi.global.settings.get('scrollback'), 10) || 250)) { | |
220 | $('.msg:first', this.$messages).remove(); | |
221 | this.msg_count--; | |
222 | } | |
50ac472f D |
223 | }, |
224 | ||
c794b877 | 225 | |
50ac472f D |
226 | topic: function (topic) { |
227 | if (typeof topic !== 'string' || !topic) { | |
228 | topic = this.model.get("topic"); | |
229 | } | |
230 | ||
247dd7ac | 231 | this.model.addMsg('', '== ' + _kiwi.global.i18n.translate('client_views_channel_topic').fetch(this.model.get('name'), topic), 'topic'); |
50ac472f D |
232 | |
233 | // If this is the active channel then update the topic bar | |
234 | if (_kiwi.app.panels().active === this) { | |
235 | _kiwi.app.topicbar.setCurrentTopic(this.model.get("topic")); | |
236 | } | |
dfb5209c JA |
237 | }, |
238 | ||
239 | // Click on a nickname | |
240 | nickClick: function (event) { | |
241 | var nick = $(event.currentTarget).text(), | |
242 | members = this.model.get('members'), | |
d62fa271 | 243 | are_we_an_op = !!members.getByNick(_kiwi.app.connections.active_connection.get('nick')).get('is_op'), |
dfb5209c JA |
244 | member, query, userbox, menubox; |
245 | ||
246 | if (members) { | |
247 | member = members.getByNick(nick); | |
248 | if (member) { | |
dfb5209c | 249 | userbox = new _kiwi.view.UserBox(); |
d62fa271 D |
250 | userbox.setTargets(member, this.model); |
251 | userbox.displayOpItems(are_we_an_op); | |
0826460d | 252 | |
dfb5209c JA |
253 | menubox = new _kiwi.view.MenuBox(member.get('nick') || 'User'); |
254 | menubox.addItem('userbox', userbox.$el); | |
96910370 | 255 | menu.showFooter(false); |
dfb5209c | 256 | menubox.show(); |
0826460d | 257 | |
dfb5209c JA |
258 | // Position the userbox + menubox |
259 | (function() { | |
260 | var t = event.pageY, | |
261 | m_bottom = t + menubox.$el.outerHeight(), // Where the bottom of menu will be | |
262 | memberlist_bottom = this.$el.parent().offset().top + this.$el.parent().outerHeight(); | |
263 | ||
264 | // If the bottom of the userbox is going to be too low.. raise it | |
265 | if (m_bottom > memberlist_bottom){ | |
266 | t = memberlist_bottom - menubox.$el.outerHeight(); | |
267 | } | |
268 | ||
269 | // Set the new positon | |
270 | menubox.$el.offset({ | |
271 | left: event.clientX, | |
272 | top: t | |
273 | }); | |
274 | }).call(this); | |
275 | } | |
276 | } | |
3499d625 D |
277 | }, |
278 | ||
279 | ||
280 | chanClick: function (event) { | |
425efe7a JA |
281 | var target = (event.target) ? $(event.target).data('channel') : $(event.srcElement).data('channel'); |
282 | ||
283 | _kiwi.app.connections.active_connection.gateway.join(target); | |
3499d625 D |
284 | }, |
285 | ||
286 | ||
287 | mediaClick: function (event) { | |
288 | var $media = $(event.target).parents('.media'); | |
289 | var media_message; | |
290 | ||
291 | if ($media.data('media')) { | |
292 | media_message = $media.data('media'); | |
293 | } else { | |
294 | media_message = new _kiwi.view.MediaMessage({el: $media[0]}); | |
295 | ||
296 | // Cache this MediaMessage instance for when it's opened again | |
297 | $media.data('media', media_message); | |
298 | } | |
299 | ||
300 | media_message.toggle(); | |
301 | }, | |
302 | ||
303 | ||
304 | // Cursor hovers over a message | |
305 | msgEnter: function (event) { | |
306 | var nick_class; | |
307 | ||
308 | // Find a valid class that this element has | |
309 | _.each($(event.currentTarget).parent('.msg').attr('class').split(' '), function (css_class) { | |
310 | if (css_class.match(/^nick_[a-z0-9]+/i)) { | |
311 | nick_class = css_class; | |
312 | } | |
313 | }); | |
314 | ||
315 | // If no class was found.. | |
316 | if (!nick_class) return; | |
317 | ||
318 | $('.'+nick_class).addClass('global_nick_highlight'); | |
319 | }, | |
320 | ||
321 | ||
322 | // Cursor leaves message | |
323 | msgLeave: function (event) { | |
324 | var nick_class; | |
325 | ||
326 | // Find a valid class that this element has | |
327 | _.each($(event.currentTarget).parent('.msg').attr('class').split(' '), function (css_class) { | |
328 | if (css_class.match(/^nick_[a-z0-9]+/i)) { | |
329 | nick_class = css_class; | |
330 | } | |
331 | }); | |
332 | ||
333 | // If no class was found.. | |
334 | if (!nick_class) return; | |
335 | ||
336 | $('.'+nick_class).removeClass('global_nick_highlight'); | |
337 | }, | |
dfb5209c | 338 | }); |