543 lines
22 KiB
JavaScript
543 lines
22 KiB
JavaScript
document.observe("dom:loaded", function() {
|
||
(function(){
|
||
function is_ie6(){
|
||
return ((window.XMLHttpRequest == undefined) && (ActiveXObject != undefined));
|
||
}
|
||
|
||
var notifications;
|
||
var unread_count = 0;
|
||
var notifications_count = $('notifications_count');
|
||
var notifications_menu = $('notifications_menu');
|
||
var notifications_summary, notifications_detail;
|
||
|
||
var Render = {
|
||
summary_names : function(names) {
|
||
if (names.length > 3) {
|
||
return new Template('#{names}和另外#{other}人').evaluate({
|
||
'names' : names.clone().splice(0,3).join(','), 'other' : names.length - 3
|
||
});
|
||
} else {
|
||
return names.join(',');
|
||
}
|
||
},
|
||
|
||
template_blog_comment : function(notification) {
|
||
this.render_comments_common_template(notification, 'blog', '回复了您的博客文章');
|
||
},
|
||
|
||
template_blog_comment_other : function(notification) {
|
||
this.render_comments_common_template(notification, 'blog', '回复了您回复过的博客文章');
|
||
},
|
||
|
||
template_topic_post : function(notification) {
|
||
this.render_comments_common_template(notification, 'topic', '回复了您的论坛主题', 'posts');
|
||
},
|
||
|
||
template_topic_post_other : function(notification) {
|
||
this.render_comments_common_template(notification, 'topic', '回复了您回复过的论坛主题', 'posts');
|
||
},
|
||
|
||
template_group_topic_post : function(notification) {
|
||
this.render_comments_common_template(notification, 'topic', '回复了您的群组主题', 'posts');
|
||
},
|
||
|
||
template_group_topic_post_other : function(notification) {
|
||
this.render_comments_common_template(notification, 'topic', '回复了您回复过的群组主题', 'posts');
|
||
},
|
||
|
||
template_news_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'news', '评论了您的资讯文章');
|
||
},
|
||
|
||
template_news_comment_other: function(notification) {
|
||
this.render_comments_common_template(notification, 'news', '评论了您评论过的资讯文章');
|
||
},
|
||
|
||
template_essence_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'essence', '评论了您的精华文章');
|
||
},
|
||
|
||
template_essence_comment_other: function(notification) {
|
||
this.render_comments_common_template(notification, 'essence', '评论了您评论过的精华文章');
|
||
},
|
||
|
||
template_problem_solution: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '回答了您的问题', 'solutions');
|
||
},
|
||
|
||
template_problem_solution_other: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '回答了您回答过的问题', 'solutions');
|
||
},
|
||
|
||
template_problem_solution_follow: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '回答了您关注的问题', 'solutions');
|
||
},
|
||
|
||
template_problem_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '评论了您的问题', 'comments');
|
||
},
|
||
|
||
template_problem_comment_follow: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '评论了您关注的问题', 'comments');
|
||
},
|
||
|
||
template_problem_follow: function(notification) {
|
||
this.render_comments_common_template(notification, 'problem', '关注了您的问题', 'follows');
|
||
},
|
||
|
||
template_solution_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'solution', '评论了您的回答', 'comments');
|
||
},
|
||
|
||
template_event_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'event', '评论了您的活动', 'comments');
|
||
},
|
||
|
||
template_event_comment_other: function(notification) {
|
||
this.render_comments_common_template(notification, 'event', '评论了您评论过的活动', 'comments');
|
||
},
|
||
|
||
template_event_comment_member: function(notification) {
|
||
this.render_comments_common_template(notification, 'event', '评论了您参与的活动', 'comments');
|
||
},
|
||
|
||
template_page_comment: function(notification) {
|
||
this.render_comments_common_template(notification, 'page', '评论了您的知识库', 'comments');
|
||
},
|
||
|
||
template_page_comment_other: function(notification) {
|
||
this.render_comments_common_template(notification, 'page', '评论了您评论过的知识库', 'comments');
|
||
},
|
||
|
||
render_comments_common_template : function(notification, subject, title, comments) {
|
||
comments = comments || 'comments';
|
||
var names = notification[comments].map(function(comment) { return comment.user.name; }).uniq();
|
||
var summary = this.summary_names(names) + title;
|
||
|
||
var link = new Template(' <span class="subject_link"><a href="#{url}" target="_blank">#{title}</a></span>').evaluate({
|
||
'summary' : summary, 'url' : notification[subject].url, 'title' : notification[subject].title
|
||
});
|
||
var detail_items = new Element('div', {'class' : 'detail_items'});
|
||
notification[comments].each(function(comment, index) {
|
||
if (index > 2) {
|
||
var template = new Template('<div class="notification_detail_item clearfix" style="display:none;"><span class="left"><a href="#{user_url}" target="_blank">#{user_name}</a>:#{body} </span><span class="time">#{time}</span></div>')
|
||
} else {
|
||
var template = new Template('<div class="notification_detail_item clearfix"><span class="left"><a href="#{user_url}" target="_blank">#{user_name}</a>:#{body}</span> <span class="time">#{time}</span></div>')
|
||
}
|
||
detail_items.insert(template.evaluate({
|
||
user_url : comment.user.url, user_name : comment.user.name, body : comment.body, time : comment.created_at
|
||
}));
|
||
if (comment.url) {
|
||
var comment_link = ' <a target="_blank" href="' + comment.url + '">查看</a>';
|
||
detail_items.select(":last-child .left")[0].insert(comment_link);
|
||
}
|
||
if (index === 2 && notification[comments].length > 3) {
|
||
var actions = new Element('div', {'class' : 'notification_detail_item clearfix'});
|
||
var show_all = new Element('a', {'class': 'show_all'}).update('查看另外'+ (notification[comments].length - 3) + '条' );
|
||
show_all.observe('click', function(ev) {
|
||
this.up().siblings().each(Element.show);
|
||
this.up().hide();
|
||
});
|
||
actions.insert(show_all);
|
||
detail_items.insert(actions);
|
||
}
|
||
});
|
||
|
||
this.render_common_template(notification, {summary : summary, detail_title : summary + link, detail_items : detail_items});
|
||
},
|
||
|
||
template_subscription: function(notification) {
|
||
var names = notification.subscribers.map(function(subscriber) { return subscriber.name; }).uniq();
|
||
var summary = new Template('#{names}关注了您').evaluate({
|
||
names : this.summary_names(names)
|
||
});
|
||
|
||
var detail_items = new Element('div', {'class' : 'detail_items'});
|
||
notification.subscribers.each(function(subscriber){
|
||
detail_items.insert(new Template('<div class="notification_detail_item clearfix"><div class="logo"><a href="#{user_url}" target="_blank"><img src="#{logo_path}" /></a></div><a href="#{user_url}" target="_blank">#{user_name}</a></div>').evaluate({
|
||
user_url : subscriber.url, user_name : subscriber.name, logo_path : subscriber.logo_path
|
||
}));
|
||
});
|
||
this.render_common_template(notification, {summary : summary, detail_title : summary, detail_items : detail_items});
|
||
},
|
||
|
||
template_common: function(notification) {
|
||
this.render_common_template(notification, {summary : notification.title,
|
||
detail_title : notification.title, detail_content : notification.detail,
|
||
detail_notice : notification.notice});
|
||
},
|
||
|
||
render_common_template: function(notification, params){
|
||
var summary = new Element('div', {id: 'notification_summary_' + notification.id, 'class' : "notification_summary clearfix"});
|
||
var summary_title = new Element('div', {'class' : 'left'}).update(params.summary);
|
||
var time = '<span class="time">' + notification.updated_at + '</span>';
|
||
if (!notification.read) {
|
||
summary.addClassName("unread");
|
||
}
|
||
summary.update(summary_title).insert(time);
|
||
notifications_summary.insert(summary);
|
||
|
||
var detail = new Element('div', {id : 'notification_' + notification.id, 'class' : 'notification_detail clearfix'});
|
||
detail.update('<div class="notification_detail_title clearfix"></div><div class="notification_detail_content clearfix"></div>').hide();
|
||
var detail_title = new Element('div', {'class' : 'left'}).update(params.detail_title);
|
||
detail.down('.notification_detail_title').insert(detail_title).insert(time);
|
||
var content = detail.down('.notification_detail_content');
|
||
if (params.detail_content) {
|
||
content.insert(new Element('div', {'class' : 'system_message'}).insert(params.detail_content));
|
||
}
|
||
if (params.detail_items) { content.insert(params.detail_items); }
|
||
if (params.detail_notice) {
|
||
var notice = new Element('div', {'class' : 'notification_detail_notice clearfix'}).update(params.detail_notice);
|
||
detail.insert({bottom : notice});
|
||
}
|
||
notifications_detail.insert(detail);
|
||
|
||
summary.observe('click', function(ev) {
|
||
if (notifications_summary.down('.current')) {
|
||
notifications_summary.down('.current').removeClassName('current');
|
||
}
|
||
this.addClassName('current');
|
||
summary_to_detail();
|
||
});
|
||
}
|
||
}
|
||
|
||
function refresh_paginate_button() {
|
||
var current = notifications_detail.down('.current')
|
||
if (current.next('.notification_detail')) {
|
||
$('next_button').removeClassName('disable');
|
||
} else {
|
||
$('next_button').addClassName('disable');
|
||
}
|
||
if (current.previous('.notification_detail')) {
|
||
$('prev_button').removeClassName('disable');
|
||
} else {
|
||
$('prev_button').addClassName('disable');
|
||
}
|
||
}
|
||
|
||
var change_page_effect_running = false;
|
||
function change_page_effect(from, to, reverse) {
|
||
var topOffset = from.positionedOffset()[1] + 'px';
|
||
var from_status, to_status;
|
||
change_page_effect_running = true;
|
||
function clean_style(effect){
|
||
if (effect.element.id === from.id) {
|
||
from_status = true;
|
||
} else {
|
||
to_status = true;
|
||
}
|
||
if (from_status && to_status) {
|
||
from.writeAttribute('style', 'display:none');
|
||
to.writeAttribute('style', '');
|
||
change_page_effect_running = false;
|
||
if (!is_ie6() && notifications_detail.visible()) {
|
||
var link = notifications_detail.down('.current').select('a').first();
|
||
if (link) { link.focus(); }
|
||
}
|
||
}
|
||
}
|
||
var width = notifications_menu.getWidth();
|
||
var widthPx = width + 'px';
|
||
if (reverse) {
|
||
to.setStyle({position: 'absolute', left: '-' + widthPx, width: widthPx, top: topOffset}).show();
|
||
Effect.multiple([from, to], Effect.Move, {speed: 0, x: width, duration: 0.15, afterFinish: clean_style});
|
||
} else {
|
||
to.setStyle({position: 'absolute', left: widthPx, width: widthPx, top: topOffset}).show();
|
||
Effect.multiple([from, to], Effect.Move, {speed: 0, x: -width, duration: 0.15, afterFinish: clean_style});
|
||
}
|
||
}
|
||
|
||
function read_detail(detail) {
|
||
$('notification_summary_' + detail.id.split('_').last()).removeClassName('unread');
|
||
}
|
||
|
||
function change_detail_page(current, to, reverse) {
|
||
current.removeClassName('current');
|
||
to.addClassName('current');
|
||
var id = to.id.split('_').last();
|
||
notifications_summary.down('.current').removeClassName('current');
|
||
notifications_summary.down('#notification_summary_' + id).addClassName('current');
|
||
change_page_effect(current, to, reverse);
|
||
read_detail(to);
|
||
refresh_paginate_button();
|
||
}
|
||
|
||
function next_detail() {
|
||
var current = notifications_detail.down('.current');
|
||
var next_page = current.next('.notification_detail');
|
||
if (next_page) {
|
||
change_detail_page(current, next_page);
|
||
}
|
||
}
|
||
|
||
function prev_detail() {
|
||
var current = notifications_detail.down('.current');
|
||
var prev_page = current.previous('.notification_detail');
|
||
if (prev_page) {
|
||
change_detail_page(current, prev_page, true);
|
||
}
|
||
}
|
||
|
||
function init_detail_paginate() {
|
||
var paginate = new Element('span', {'class' : 'paginate'});
|
||
var prev = new Element('a', {id : 'prev_button'}).update('‹ 上一条');
|
||
var next = new Element('a', {id : 'next_button'}).update('下一条 ›');
|
||
next.observe('click', function(ev) {
|
||
if (!this.hasClassName('disable')){
|
||
next_detail();
|
||
}
|
||
});
|
||
prev.observe('click', function(ev) {
|
||
if (!this.hasClassName('disable')){
|
||
prev_detail();
|
||
}
|
||
});
|
||
paginate.insert(prev).insert('<span class="separated">|</span>').insert(next);
|
||
return paginate;
|
||
}
|
||
|
||
function summary_to_detail() {
|
||
var summary = notifications_summary.down('.current');
|
||
var detail = notifications_detail.down('#notification_' + summary.id.split('_').last());
|
||
var prev = notifications_detail.down('.current');
|
||
if (prev) {
|
||
prev.removeClassName('current').hide();
|
||
}
|
||
detail.addClassName('current').show();
|
||
read_detail(detail);
|
||
refresh_paginate_button();
|
||
change_page_effect(notifications_summary, notifications_detail);
|
||
}
|
||
|
||
function hotkey_left() {
|
||
if (notifications_detail.visible()) {
|
||
if (notifications_detail.down('.current').previous('.notification_detail')) {
|
||
prev_detail();
|
||
} else {
|
||
change_page_effect(notifications_detail, notifications_summary, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
function hotkey_right() {
|
||
if (notifications_detail.visible()) {
|
||
next_detail();
|
||
} else {
|
||
if (!notifications_summary.down('.current')) {
|
||
notifications_summary.down('.notification_summary').addClassName('current');
|
||
}
|
||
summary_to_detail();
|
||
}
|
||
}
|
||
|
||
function hotkey_up() {
|
||
if (notifications_summary.visible()) {
|
||
var current_summary = notifications_summary.down('.current');
|
||
if (current_summary) {
|
||
if (current_summary.previous('.notification_summary')) {
|
||
current_summary.removeClassName('current');
|
||
current_summary.previous('.notification_summary').addClassName('current');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function hotkey_down() {
|
||
if (notifications_summary.visible()) {
|
||
var current_summary = notifications_summary.down('.current');
|
||
if (current_summary) {
|
||
if (current_summary.next('.notification_summary')) {
|
||
current_summary.removeClassName('current');
|
||
current_summary.next('.notification_summary').addClassName('current');
|
||
}
|
||
} else {
|
||
notifications_summary.down('.notification_summary').addClassName('current');
|
||
}
|
||
}
|
||
}
|
||
|
||
function hotkey_enter(event) {
|
||
if (notifications_summary.visible() && notifications_summary.down('.current')) {
|
||
summary_to_detail();
|
||
event.stop();
|
||
}
|
||
}
|
||
|
||
function hotkey_backspace() {
|
||
if (notifications_detail.visible()) {
|
||
change_page_effect(notifications_detail, notifications_summary, true);
|
||
}
|
||
}
|
||
|
||
function init_notification_menu() {
|
||
notifications_menu = new Element('div', {'id': 'notifications_menu'});
|
||
notifications_summary = new Element('div', {'id': 'notifications_summary'});
|
||
notifications_summary.update('<div class="menu_title clearfix"><span class="title">提醒</span><span class="all"><a href="http://my.iteye.com/notifications">查看所有 »</a></span></div>');
|
||
notifications_menu.insert(notifications_summary);
|
||
|
||
notifications_detail = new Element('div', {'id': 'notifications_detail'});
|
||
var detail_menu_title = new Element('div', {'class' : 'menu_title clearfix'});
|
||
var return_button = new Element('span', {'class' : 'return left'}).update('« 返回通知列表');
|
||
detail_menu_title.insert(return_button).insert(init_detail_paginate());
|
||
|
||
return_button.observe('click', function(ev) {
|
||
change_page_effect(notifications_detail, notifications_summary, true);
|
||
});
|
||
notifications_detail.insert(detail_menu_title).hide();
|
||
notifications_menu.insert(notifications_detail);
|
||
$('user_nav').insert({after: notifications_menu});
|
||
|
||
$(document).observe('keydown', function(event) {
|
||
if (notifications_menu.visible() && notifications.length > 0 && !change_page_effect_running){
|
||
var keyCode = event.keyCode;
|
||
if (keyCode == Event.KEY_LEFT || keyCode == 72 ) {
|
||
hotkey_left();
|
||
event.stop();
|
||
} else if (keyCode == Event.KEY_RIGHT || keyCode == 76) {
|
||
hotkey_right();
|
||
event.stop();
|
||
} else if (keyCode == Event.KEY_UP || keyCode == 75) {
|
||
hotkey_up();
|
||
event.stop();
|
||
} else if (keyCode == Event.KEY_DOWN || keyCode == 74) {
|
||
hotkey_down();
|
||
event.stop();
|
||
} else if (keyCode == Event.KEY_RETURN) {
|
||
hotkey_enter(event);
|
||
} else if (keyCode == Event.KEY_BACKSPACE) {
|
||
hotkey_backspace();
|
||
event.stop();
|
||
} else if (keyCode == Event.KEY_ESC) {
|
||
hide_notification_menu();
|
||
}
|
||
}
|
||
});
|
||
|
||
$(document.body).observe('click', function(event) {
|
||
if (notifications_menu.visible()) {
|
||
var clicked = event.element();
|
||
if (!(clicked === notifications_menu || clicked.up("#notifications_menu"))) {
|
||
hide_notification_menu();
|
||
}
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
function update_notifications_menu() {
|
||
$$('#notifications_menu .notification_summary').each(Element.remove);
|
||
$$('#notifications_menu .notification_detail').each(Element.remove);
|
||
|
||
if (notifications.length > 0) {
|
||
notifications.each(function(notification) {
|
||
if (notification) {
|
||
if (Render['template_' + notification.type]) {
|
||
Render['template_' + notification.type](notification);
|
||
} else {
|
||
Render['template_common'](notification);
|
||
}
|
||
};
|
||
});
|
||
} else {
|
||
notifications_summary.insert('<div class="notification_summary">当前没有提醒信息</div>');
|
||
}
|
||
}
|
||
|
||
function refresh_unread_count(count) {
|
||
unread_count = count;
|
||
notifications_count.update(unread_count);
|
||
if (count > 0) {
|
||
notifications_count.addClassName('new_notice').writeAttribute('title', '有' + count + '条未读消息');
|
||
} else {
|
||
notifications_count.removeClassName('new_notice').writeAttribute('title', '没有未读消息');
|
||
}
|
||
}
|
||
|
||
function update_unread_count(pe) {
|
||
new Ajax.JSONRequest('http://n.iteye.com/notifications/unread_count.json', {
|
||
method: "get",
|
||
onComplete: function(response) {
|
||
var json_respone = response.responseJSON;
|
||
refresh_unread_count(json_respone.unread_count);
|
||
}
|
||
});
|
||
}
|
||
|
||
function update_notifications() {
|
||
var loading = new Element('div', {id : 'notifications_loading'}).update('载入中...');
|
||
notifications_menu.insert({top: loading});
|
||
new Ajax.Request('/notifications.json', {
|
||
method: "get",
|
||
onComplete: function(response) {
|
||
var json_respone = response.responseJSON;
|
||
notifications = json_respone;
|
||
update_notifications_menu();
|
||
loading.remove();
|
||
mark_as_read();
|
||
}
|
||
});
|
||
}
|
||
|
||
function mark_as_read() {
|
||
var unread_ids = notifications.map(function(notification){
|
||
if (!notification.read) {
|
||
return notification.id;
|
||
}
|
||
}).without(undefined);
|
||
if (unread_ids.length > 0) {
|
||
new Ajax.Request('/notifications/read.json?ids=' + unread_ids.join(','), {
|
||
method: "put",
|
||
onComplete: function(response) {
|
||
notifications.each(function(notification){notification.read = true});
|
||
refresh_unread_count(response.responseJSON.unread_count);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
function show_notification_menu() {
|
||
if (notifications_menu === null) {
|
||
init_notification_menu();
|
||
} else {
|
||
notifications_summary.show();
|
||
}
|
||
if (unread_count > 0 || notifications === undefined) {
|
||
update_notifications();
|
||
}
|
||
notifications_menu.show();
|
||
notifications_count.addClassName('clicked');
|
||
}
|
||
|
||
function hide_notification_menu() {
|
||
notifications_summary.hide();
|
||
notifications_detail.hide();
|
||
notifications_menu.hide();
|
||
notifications_count.removeClassName('clicked');
|
||
}
|
||
|
||
function trigger_menu() {
|
||
if (notifications_count.hasClassName('clicked')) {
|
||
hide_notification_menu();
|
||
} else {
|
||
show_notification_menu();
|
||
}
|
||
}
|
||
|
||
if (notifications_count) {
|
||
notifications_count.observe('click', function(event) {
|
||
trigger_menu();
|
||
event.stop();
|
||
});
|
||
$(document).observe('keydown', function(event){
|
||
// alt + n
|
||
if (event.keyCode == 78 && event.altKey) {
|
||
trigger_menu();
|
||
}
|
||
});
|
||
update_unread_count();
|
||
new PeriodicalExecuter(update_unread_count, 60);
|
||
}
|
||
})();
|
||
})
|