javaeye3/public/javascripts/notifications.js

543 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
})();
})