1/* used in user_notify.html */ 2$(function(){ 3 4 var data = window._user_notifies; 5 6 /* load css if needed */ 7 var user_notify_css_loaded = false; 8 $('.user-notify-loaded').first().each(function(){ 9 user_notify_css_loaded = window.getComputedStyle(this,':before').conten 10 }); 11 if (!user_notify_css_loaded) { 12 $('<style></style>').attr({ 13 rel:'stylesheet', 14 href:'/static/user-notify/user-notify.css' 15 }).appendTo('head'); 16 } 17 18 var lang = navigator.language || navigator.userLanguage || 'en'; 19 lang = lang.toLowerCase().split(/[-_]/)[0]; 20 21 if (lang == 'ja') { 22 $('#user-notifies .user-notify-nothing [for-lang="en"]').remove(); 23 } else { 24 $('#user-notifies .user-notify-nothing [for-lang="ja"]').remove(); 25 } 26 var screen_key = data.cookie_path.replace(/\//g, ""); 27 var RSNTFY_COOKIE_NAME = 'rsntfy' + (screen_key || ''); 28 29 var cookie_name = RSNTFY_COOKIE_NAME; 30 var user_read_at = new Date(0); 31 function checkUserReadAt() { 32 var user_read_at_on_cookie = $.cookie(cookie_name); 33 if (user_read_at_on_cookie) { 34 user_read_at.setTime(parseFloat(user_read_at_on_cookie, 10)); 35 if (isNaN(user_read_at)) { 36 user_read_at = new Date(0); 37 } 38 } else { 39 user_read_at = new Date(0); 40 } 41 console.log('user read until (on cookie):' + user_read_at.toISOString()); 42 } 43 // checkUserReadAt(); // execute in sortNotifies() 44 45 var $toggle = $('#user-notifies-toggle'), 46 $notifies_box = $('#user-notifies').appendTo('body'), 47 $notifies = $notifies_box.children('.user-notifies-content'), 48 $notifies_title = $notifies.children('.user-notifies-title'), 49 tmpl_doc = new DOMParser().parseFromString('<html></html>', 'text/html'), 50 $notify_template = $( 51 $notifies_box.find('.user-notify.template').removeClass('template') 52 .remove().outerHTML()); 53 54 function pz2(num){ return (num < 10) ? '0' + num : '' + num; } 55 56 function addNotify(notify){ 57 58 $notifies_box.find('.user-notify-nothing').remove(); 59 60 var display_at = new Date(notify.display_at), 61 updated_at = new Date(notify.updated_at), 62 overviews = notify.overview_text, 63 overview = overviews[lang] || overviews['en'] || '', 64 details = notify.detail_html; 65 66 if (isNaN(display_at)) { 67 console.error('display_at is not ISO8601(yyyy-mm-ddThh:mm:ss+hh:mm):' + notify.display_at); 68 return; 69 } 70 if (isNaN(updated_at)) { 71 console.error('update_at is not ISO8601(yyyy-mm-ddThh:mm:ss+hh:mm):' + notify.updated_at); 72 return; 73 } 74 75 overview = $('<div></div>').text(overview.replace(/\n/g, '__BBRR__')).html().replace(/__BBRR__/g, '<br>\n'); 76 77 var display_at_str = 78 ((new Date().getFullYear() != display_at.getFullYear()) ? (display_at.getFullYear() + '-') : '') 79 + pz2(display_at.getMonth() + 1) 80 + '-' 81 + pz2(display_at.getDate()); 82 83 var $notify = $notify_template.clone() 84 .toggleClass('has-detail', !!notify.detail_html) 85 .attr('data-notify-display', display_at.toISOString()) 86 .attr('data-notify-updated', updated_at.toISOString()) 87 .find('.user-notify-date').text(display_at_str).end() 88 .find('.user-notify-message').html(overview).end() 89 .insertAfter($notifies_title); 90 91 if (details) { 92 var detail = $('<div></div>').html(details[lang] || details['en'] || '').html(), 93 $notify_detail = $notify 94 .find('.user-notify-detail-content').html(detail); 95 $notify_detail 96 .on('resized', function(ev){ 97 $(this).parent('.user-notify-detail') 98 .css('max-height', $(this).outerHeight() + 'px'); 99 }) 100 .trigger('resized'); 101 } 102 return $notify; 103 } 104 105 function makeNotifies(notifies) { 106 notifies.forEach(function(notify){ addNotify(notify); }); 107 } 108 109 110 // data.notifies.sort(function(v){ return v.display_at < v.display_at ? -1 : 1 }); 111 makeNotifies(data.notifies); 112 sortNotifies(); 113 114 var _autoshow_t, _autohide_t; 115 116 function sortNotifies(){ 117 // sort, set unread, auto show when has unread notfies. 118 119 // sort 120 var notifies = $('#user-notifies > .user-notifies-content > .user-notify').toArray(); 121 notifies.sort(function(a, b){ 122 return new Date($(a).attr('data-notify-display')) < new Date($(b).attr('data-notify-display')) ? -1 : 1; 123 }); 124 var notify, $notifies_box = $('#user-notifies > .user-notifies-content'); 125 while (notify = notifies.pop()){ 126 $notifies_box.append(notify); 127 } 128 129 // check unread 130 checkUserReadAt(); 131
132 $notifies_box.children('.user-notify').each(function(){ 133 var $notify = $(this); 134 var data_notify_updated_attr = $notify.attr('data-notify-updated'); 135 var notify_updated_at_dt = new Date(data_notify_updated_attr); 136 var is_read = notify_updated_at_dt < user_read_at; 137 $notify.toggleClass('user-read', is_read); 138 }); 139 var unread_cnt = $notifies_box.children('.user-notify:not(.user-read)').length; 140 $toggle.toggleClass('has-unread', unread_cnt > 0); 141 142 // auto show unread notifies 143 clearTimeout(_autoshow_t); 144 if (unread_cnt > 0) { 145 _autoshow_t = setTimeout(function(){ 146 _autoshow_t = null; 147 $notifies_box.find('.user-notify:not(.user-read) .user-notify-overview').addClass('opened'); 148 showNotifies(true); 149 }, 2000); 150 } 151 } 152 153 function clearUnread(){ 154 $toggle.removeClass('has-unread'); 155 $.cookie(cookie_name, new Date().getTime(), { 156 path:data.cookie_path, 157 expires:'never', 158 }); 159 } 160 161 function showNotifies(is_auto) { 162 var is_shown = $notifies_box.is('.shown'); 163 if (!is_shown) { 164 // do show 165 var rect = $toggle[0].getBoundingClientRect(); 166 $.setStyle( 167 '#user-notifies.shown > .user-notifies-content { margin-top:'+ (rect.bottom + 5) +'px; }', 168 'style-notifies') 169 .appendTo('body'); 170 171 $notifies_box.addClass('shown'); 172 $toggle.addClass('shown'); 173 174 if (is_auto) { 175 $notifies_box.addClass('auto-shown'); 176 } else { 177 $notifies_box.removeClass('auto-shown'); 178 } 179 180 // èªå表示ããã®èªåé表示 181 if (is_auto) { 182 _autohide_t = setTimeout(function(){ 183 if (data.auto_clear_unread) { 184 clearUnread(); 185 } 186 hideNotifies(); 187 }, 7000); 188 } 189 190 } else { 191 $notifies_box.removeClass('shown'); 192 $toggle.removeClass('shown'); 193 } 194 } 195 196 function hideNotifies() { 197 $notifies_box.removeClass('shown').removeClass('auto-shown'); 198 } 199 200 // toggle 201 $toggle.on('click', function(ev){ 202 ev.preventDefault(); 203 ev.stopPropagation(); 204 showNotifies(); 205 clearTimeout(_autohide_t); 206 setTimeout(clearUnread, 100); 207 }); 208 209 // detail 210 $notifies_box 211 .one('mouseenter', function(ev){ 212 // ããã¼ã§èªåé表示ãæå¶ 213 console.log('mouseenter notfies_box'); 214 clearTimeout(_autohide_t); 215 if (data.auto_clear_unread) { 216 clearUnread(); 217 } 218 }) 219 .on('click', function(ev){ 220 ev.stopPropagation(); 221 clearUnread(); 222 }) 223 .on('click', '.user-notify.has-detail > .user-notify-overview', function(ev){ 224 ev.preventDefault(); 225 $(this).toggleClass('opened'); 226 }); 227 228 229 // close 230 $('#user-notifies-close').on('click', function(ev){ 231 ev.preventDefault(); 232 ev.stopPropagation(); 233 $notifies_box.removeClass('shown'); 234 $toggle.removeClass('shown'); 235 clearUnread(); 236 }); 237 238 // close anywhere 239 $(document).on('click', function(ev){ 240 $notifies_box.removeClass('shown'); 241 $toggle.removeClass('shown'); 242 }); 243 244 /** 245 * usage: 246 * $(document).trigger('addnotifies', [ 247 * [ { notify1, notify2, ...} ], // notifies 248 * 'whichuser_' + id, // login user key for cookie (optional) 249 * 'yyyy-mm-ddTHH:MM+hh:mm', // login user read at last in iso8601 (optional) 250 * ]); 251 */ 252 $(document).on('addnotifies', function(ev, notifies, user_key, user_read_at){ 253 console.log('addnotifies', arguments); 254 if (user_key) { 255 cookie_name = RSNTFY_COOKIE_NAME + (user_key || ''); 256 } 257 if (user_read_at) { 258 var user_read_dt = new Date(user_read_at); 259 if (isNaN(user_read_dt)) { 260 console.error('addnotifies:invalid user_read_at:' + user_read_at); 261 } else { 262 $.cookie(cookie_name, user_read_dt.getTime()); 263 checkUserReadAt(); 264 } 265 } 266 notifies.forEach(function(notify){ 267 addNotify(notify); 268 }); 269 sortNotifies(); 270 }); 271 272});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.