app/assets/javascripts/lib/reader/manage.js
// manage
updater("manage_item", function(){
if(!Manage.Item.loaded){
Manage.Item.load();
return;
}
var data = Manage.Item.get_items();
var tmpl = Template.get("man_items").compile();
var now = new Date / 1000;
var fmt = function(item){
var sid = item.subscribe_id;
item = subs_item(sid);
var classname = TRSelector.cart.has(sid) ? "selected" : "";
return tmpl(item, {
update : (now - item.modified_on).toRelativeDate(),
notify_text: item.ignore_notify ? "無効" : "有効",
classname : classname
})
}
var param = {};
param["sortmode_"+MI.sort_mode] = "selected";
this.innerHTML = [
Template.get("man_item_header").fill({
has_prev : Manage.Item.has_prev() ? "" : "disable",
has_next : Manage.Item.has_next() ? "" : "disable"
},param),
data.list.slice(MI.offset, MI.offset + MI.perpage).map(fmt).join(""),
"</table></div>"
].join("");
addEvent(_$("manage_table"), "selectstart", Event.stop);
addEvent(_$("manage_table"), "mousedown", Event.stop);
update("manage_select","move_to", "manage_offset");
});
updater("manage_select",function(){
var size = TRSelector.cart.keys.length;
if(size){
if(app.state.manage_disabled){
Form.enable_all("manage_control");
removeClass("manage_control", "grayout");
app.state.manage_disabled = false;
}
Manage.message(size + ' items selected');
} else {
Manage.message('Select item(s) you want to edit');
addClass("manage_control", "grayout");
Form.disable_all("manage_control");
app.state.manage_disabled = true;
}
});
var Selector = Class.create().extend({
initialize : function(){
var self = this;
Object.extend(this,{
mousedown : function(event){self.onmousedown.call(self,this,event)},
mouseover : function(event){self.onmouseover.call(self,this,event)},
mouseout : function(event){self.onmouseout.call(self,this,event)}
});
self.setup && self.setup.apply(this,arguments)
},
onmousedown : function(el,event){
app.state.mdown = true;
if(hasClass(el,"selected")){
removeClass(el, "selected");
app.state.turn = false;
} else {
addClass(el, "selected");
app.state.turn = true;
}
},
onmouseover : function(el,event){
if(app.state.mdown){
(app.state.turn) ? addClass(el, "selected") : removeClass(el, "selected")
} else {
addClass(el, "focus")
}
},
onmouseout : function(el,event){
removeClass(el, "focus")
}
});
var Cart = Class.create();
Cart.extend({
initialize : function(){
this.hash = {};
this.keys = [];
this.values = [];
},
clear : function(){
return this.initialize();
},
has : function(key){
return this.hash.hasOwnProperty("item_" + key)
},
add : function(key,value){
if(!this.has(key)){
this.hash["item_" + key] = value;
this.keys.push(key);
this.values.push(key);
}
},
remove : function(key){
if(!this.has(key)) return false;
delete this.hash["item_" + key];
var idx = this.keys.indexOf(key);
this.keys.delete_at(idx);
this.values.delete_at(idx);
return this;
},
get : function(key){
return this.hash("item_" + key)
}
});
var SelectorWithCart = Class.create().extend({
initialize : function(){
this.cart = new Cart;
},
clear: function(){
this.cart.clear();
},
_updateCart : function(element){
var change;
var sid = element.getAttribute("subscribe_id") - 0;
var chk = hasClass(element, "selected");
if(!chk){
change = this.cart.remove(sid);
} else if(!this.cart.has(sid)){
this.cart.add(sid);
change = true;
}
change && update("manage_select")
},
onmousedown : function(){
this._updateCart.apply(this,arguments);
},
onmouseover : function(){
this._updateCart.apply(this,arguments);
},
get_selected : function(){
return this.cart.keys
}
});
var ItemSelector = Class.merge(Selector, SelectorWithCart);
var TRSelector = new ItemSelector;
var Manage = {};
Manage.message = function(str){
_$("manage_select").innerHTML = str;
};
Manage.Item = {
get_items: function(){
return this.filtered || this.data;
},
offset : 0,
perpage : 20,
filter: null,
filtered : null,
set_filter: function(f){ this.filter = f },
reload_filter: function(){
if(this.filter){
this.filtered = this.data.filter(this.filter);
}
this.update();
},
loaded : false,
load : function(){
var self = this;
this.data = new Subscribe.Model;
new LDR.API("/api/subs?unread=0").post({},
function(list){
self.loaded = true;
self.data.load(list);
if(self.sort_mode){
self.do_sort()
}
if(self.filter){
self.reload_filter()
} else {
self.update()
}
});
},
search: function(){
var q = this.value;
if(q == ""){
MI.filtered = null;
MI.update();
return;
}
MI.filtered = MI.data.filter(function(item){
return contain(item.title,q)
});
MI.update()
},
do_sort: function(){
if(!this.sort_mode) return;
var data = this.get_items();
data.list.sort_by(this.sort_mode);
},
sort_mode: null,
sort: function(sort_mode){
var data = this.get_items();
if(sort_mode == this.sort_mode){
data.list.reverse();
this.update();
return;
}
this.sort_mode = sort_mode;
this.do_sort();
this.update();
},
clear_select : function(){
TRSelector.cart.clear();
this.update();
},
select_all: function(){
var data = this.get_items();
var cart = TRSelector.cart;
foreach(data.list, function(item){
var sid = item.subscribe_id;
cart.add(sid)
});
this.update();
},
page_select : function(){
var data = this.get_items();
var cart = TRSelector.cart;
data.list.slice(MI.offset, MI.offset + MI.perpage).forEach(function(item){
var sid = item.subscribe_id;
if(cart.has(sid)){
cart.remove(sid)
} else {
cart.add(sid)
}
});
this.update();
},
reverse_select : function(){
var data = this.get_items();
var cart = TRSelector.cart;
foreach(data.list,function(item){
var sid = item.subscribe_id;
if(cart.has(sid)){
cart.remove(sid)
} else {
cart.add(sid)
}
});
this.update();
},
data : null,
has_prev : function(){
return this.offset > 0
},
has_next : function(){
var data = this.get_items();
return this.offset + this.perpage < data.list.length ? true : false;
},
prev : function(){
if(this.has_prev()){
this.offset = Math.max(0,this.offset - this.perpage);
update("manage_item","mi_paging");
}
},
next : function(){
if(this.has_next()){
this.offset += this.perpage;
update("manage_item","mi_paging");
}
},
update : function(){
update("manage_item","mi_paging");
},
do_move : function(){
var sel = _$("move_to");
var to = Form.getValue(sel);
var ids = TRSelector.get_selected();
move_to(ids.join(","),to);
foreach(ids,function(sid){
var item = subs_item(sid);
if(item) item.folder = to;
});
update("manage_item")
},
toggle_notify: function(){
var ids = TRSelector.get_selected();
if(!ids.length) return;
var turn = 0;
var sids = [];
foreach(ids,function(sid,n){
var item = subs_item(sid);
if(!item) return;
if(n==0){turn = item.ignore_notify ? 0 : 1}
item.ignore_notify = turn;
sids.push(sid);
});
var api = new LDR.API("/api/feed/set_notify");
api.post({
subscribe_id:sids.join(","),
ignore : turn
},function(){
message("通知設定を変更しました")
});
update("manage_item")
},
unsubscribe: function(){
var ids = TRSelector.get_selected();
var l = ids.length;
var tmpl_confirm = 'Are you sure to remove [[ count ]] feed(s) from your subscription?';
var tmpl_progress = 'Removing feeds: [[ remain ]] items to go'
var c = confirm(tmpl_confirm.fill({count: l}));
if(!c) return;
TRSelector.clear();
foreach(ids,function(sid,n){
var api = new LDR.API("/api/feed/unsubscribe");
api.post({subscribe_id:sid},function(){
l--;
message(
tmpl_progress.fill({remain: l})
);
if(l == 0){
message('Feeds deleted');
MI.load();
}
});
});
},
touch: function(){
var ids = TRSelector.get_selected();
foreach(ids,function(sid){
var item = subs_item(sid);
if(!item) return;
if(item.unread_count > 0){
item.unread_count = 0;
var api = new LDR.API("/api/touch_all");
api.post({subscribe_id:sid})
}
});
message('Marked as read');
update("manage_item")
}
};
/*
再描画
*/
Manage.rewrite = {
}
updater("manage_offset", function(){
var tmpl = Template.get("man_offset").compile();
var folder_id = MF.folder_id;
if(folder_id == 0){
var folder_name = 'Uncategolized';
} else if (!folder_id){
var folder_name = 'All';
} else {
var folder_name = folder.id2name[folder_id];
}
var size = MI.get_items().list.length;
this.innerHTML = tmpl({
selecter_name : folder_name,
size : size,
start : MI.offset + 1,
end : Math.min(MI.offset + MI.perpage, size)
});
});
updater("mi_paging", function(){
var prev = _$("mi_prev");
var next = _$("mi_next");
MI.has_next() ? removeClass(next,"disable") : addClass(next, "disable");
MI.has_prev() ? removeClass(prev,"disable") : addClass(prev, "disable");
});
updater("move_to", function(){
this.options.length = 0;
this.options[0] = new Option('Uncategolized', "");
var op = this.options;
folder.names.map(function(v,i){
op[i+1] = new Option(v,v);
})
});
// folderの管理
updater("manage_folder", function(){
if(MF.change_flag || !folder){
MF.change_flag = false;
get_folders(updater("manage_folder"));
return;
}
var tmpl = Template.get("man_folder");
var fmt = function(v){
var id = folder.name2id[v];
return tmpl.fill({
folder:v,
id : id,
selected : MF.folder_id == id ? "selected" : ""
})
};
_$("manage_folder").innerHTML = [
'<li class="button ' + (MF.folder_id == 0 ? 'selected' : '') + '" onclick="MF.select(0)">', 'Uncategolized', '</li>',
folder.names.map(fmt).join(" ")
].join("");
update("update_folder");
update("move_to");
});
updater("update_folder",function(){
if(!MF.folder_id){
this.innerHTML = "";
return;
}
var tmpl = Template.get("manage_form").compile();
this.innerHTML = tmpl({
folder_id : MF.folder_id,
folder_name : folder.id2name[MF.folder_id]
});
ajaxize("rename_form", function(res,req){
message(folder.id2name[req.folder_id] + "->" + req.name);
folder = null;
MF.change_flag = true;
update('manage_folder');
// フィルタを変更
MI.set_filter(function(item){
return item.folder == req.name;
});
MI.load();
});
ajaxize("delete_form",{
before: function(param){
var tmpl = 'Are you sure to remove "[[folder]]"? (Items inside won\'t be removed)';
var c = confirm(
tmpl.fill({ folder: folder.id2name[param.folder_id]})
);
return c ? true : false;
},
after: function(res,req){
var fn = folder.id2name[req.folder_id];
message(fn + ' deleted');
MF.folder_id = null;
folder = null;
// フォルダ一覧を再読み込みして表示のみ更新
var rewrite = function(){
update('manage_folder');
// folderを削除
MI.data.list.filter(
function(item){ return item.folder == fn }
).forEach(
function(item){
var sid = item.subscribe_id;
subs_item(sid).folder = "";
}
);
MI.update();
}
get_folders(rewrite);
}
});
});
Manage.Folder = {
folder_id : null,
change_flag : false,
select : function(id){
if(this.folder_id == id){
this.folder_id = null;
} else {
this.folder_id = id;
}
// offsetを初期化
MI.offset = 0;
update("manage_folder");
update("update_folder");
// itemも更新
if(MI.loaded){
if(this.folder_id == null){
MI.filtered = null;
} else if(this.folder_id == 0){
MI.set_filter(function(item){
return item.folder == "";
});
return MI.reload_filter();
} else {
var folder_name = folder.id2name[id];
MI.set_filter(function(item){
return item.folder == folder_name;
});
return MI.reload_filter();
}
MI.do_sort();
MI.update()
}
},
filter: function(){ return true },
create_folder: function(callback){
var name = prompt('Folder Name',"");
if(!name) return;
var api = new LDR.API("/api/folder/create");
api.post({name:name},function(res){
message('folder created');
folder = null;
callback();
});
},
rename_folder : function(callback){
var folder_id = MF.folder_id;
if(!folder_id) return false;
var new_name = _$("rename_to").value;
if(!new_name) return false;
var api = new LDR.API("/api/folder/update");
api.post({folder_id : folder_id, name : new_name},function(){
message(folder.id2name[folder_id] + "->" + new_name);
folder = null; callback();
});
MF.change_flag = true;
return true;
},
delete_folder : function(callback){
var folder_id = MF.folder_id;
if(!folder_id) return false;
var tmpl = 'Are you sure to remove "[[folder]]"? (Items inside won\'t be removed)';
var c = confirm(
tmpl.fill({ folder: folder.id2name[folder_id]})
);
if(!c) return false;
var api = new LDR.API("/api/folder/delete");
api.post({folder_id : folder_id},function(){
message(folder.id2name[folder_id] + ' deleted');
MF.folder_id = null;
folder = null;
callback();
});
MF.change_flag = true;
return true;
}
};
Manage.show_help = function(){
if(this.disabled) return;
_$("manage_help").innerHTML = "-> " + this.title;
}
Manage.hide_help = function(){
_$("manage_help").innerHTML = "";
}
// deleteを実行
function delete_folder(folder_id){
var api = new LDR.API("/api/folder/delete");
api.post({folder_id : folder_id},function(){
message(folder.id2name[folder_id] + ' deleted');
folder = null; callback();
});
var models = SM.instances;
var folder_name = folder.id2name[folder_id];
models.invoke("delete_folder", folder_name)
}
// renameを実行
function rename_folder(folder_id, new_name){
var api = new LDR.API("/api/folder/update");
api.post({folder_id : folder_id, name : new_name},function(){
message(folder.id2name[folder_id] + "->" + new_name);
folder = null; callback();
});
var models = SM.instances;
var folder_name = folder.id2name[folder_id];
models.invoke("rename_folder", folder_name, new_name)
}
var MI = Manage.Item;
var MF = Manage.Folder;
MouseUp = new Trigger("mouseup");
MouseUp.add(True,function(){app.state.mdown = false});
MouseUp.apply();
// 描画領域を入れ替える。
function change_buffer(){
var current_buffer = _$("right_body");
var background = _$("buffer");
current_buffer.id = "buffer";
current_buffer.style.display = "none";
background.id = "right_body";
background.style.display = "block";
}
addEvent(_$("mini_window"),"dblclick",function(e){
Event.stop(e);
DOM.hide("mini_window");
});
function preview(sid){
print_feed.target = "mini_window_body";
DOM.show("mini_window");
centering("mini_window");
var item = subs_item(sid);
if(true){
var api = new LDR.API("/api/all");
api.onload = function(json){
print_feed(json)
};
api.post({
subscribe_id : sid,
limit : 1
});
}
}
function centering(element,x,y){
element = _$(element);
x = x || 0;
y = y || 0;
var w = element.offsetWidth;
var h = element.offsetHeight;
var bw = document.body.offsetWidth;
var bh = document.body.offsetHeight;
var top = (bh/2) - (h/2) -y + "px";
var left = (bw/2) - (w/2) -x + "px";
setStyle(element,{
top : top,
left : left
});
}
updater("config_form", function(){
var active = TabManager["config_form"];
(active == "config_basic") ?
Element.hide("config_submit"):
Element.show("config_submit")
})