refactor feed subscription/browser dialogs

This commit is contained in:
Andrew Dolgov 2010-11-20 21:06:36 +03:00
parent ec39a02cd8
commit 11b9d0becd
6 changed files with 310 additions and 321 deletions

View File

@ -560,109 +560,6 @@ function createFilter() {
}
}
function isValidURL(s) {
return s.match("http://") != null || s.match("https://") != null || s.match("feed://") != null;
}
function subscribeToFeed() {
try {
var form = document.forms['feed_add_form'];
var feed_url = form.feed_url.value;
if (feed_url == "") {
alert(__("Can't subscribe: no feed URL given."));
return false;
}
notify_progress(__("Subscribing to feed..."), true);
var query = Form.serialize("feed_add_form");
console.log("subscribe q: " + query);
Form.disable("feed_add_form");
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
try {
if (!transport.responseXML) {
console.log(transport.responseText);
alert(__("Server error while trying to subscribe to specified feed."));
return;
}
var result = transport.responseXML.getElementsByTagName('result')[0];
var rc = parseInt(result.getAttribute('code'));
Form.enable("feed_add_form");
notify('');
switch (rc) {
case 1:
closeInfoBox();
notify_info(__("Subscribed to %s").replace("%s", feed_url));
if (inPreferences()) {
updateFeedList();
} else {
setTimeout('updateFeedList(false, false)', 50);
}
break;
case 2:
alert(__("Specified URL seems to be invalid."));
break;
case 3:
alert(__("Specified URL doesn't seem to contain any feeds."));
break;
case 4:
new Ajax.Request("backend.php", {
parameters: 'op=rpc&subop=extractfeedurls&url=' + encodeURIComponent(feed_url),
onComplete: function(transport) {
var result = transport.responseXML.getElementsByTagName('urls')[0];
var feeds = JSON.parse(result.firstChild.nodeValue);
var select = document.getElementById("faad_feeds_container_select");
while (select.hasChildNodes()) {
select.removeChild(elem.firstChild);
}
var count = 0;
for (var feedUrl in feeds) {
select.insert(new Option(feeds[feedUrl], feedUrl, false));
count++;
}
if (count > 5) count = 5;
select.size = count;
Effect.Appear('fadd_feeds_container', {duration : 0.5});
}
});
break;
case 5:
alert(__("Couldn't download the specified URL."));
break;
case 0:
alert(__("You are already subscribed to this feed."));
break;
}
} catch (e) {
exception_error("subscribeToFeed", e);
}
} });
} catch (e) {
exception_error("subscribeToFeed", e);
}
return false;
}
function filterCR(e, f)
{
var key;
@ -857,7 +754,7 @@ function remove_splash() {
}
}
function getSelectedFeedsFromBrowser() {
/* function getSelectedFeedsFromBrowser() {
var list = $$("#browseFeedList li[id*=FBROW]");
@ -865,52 +762,15 @@ function getSelectedFeedsFromBrowser() {
list.each(function(child) {
var id = child.id.replace("FBROW-", "");
var cb = $("FBCHK-" + id);
if (cb.checked) {
if (child.hasClassName('Selected')) {
selected.push(id);
}
});
return selected;
}
} */
function updateFeedBrowser() {
try {
var query = Form.serialize("feed_browser");
Element.show('feed_browser_spinner');
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
notify('');
Element.hide('feed_browser_spinner');
var c = $("browseFeedList");
var r = transport.responseXML.getElementsByTagName("content")[0];
var nr = transport.responseXML.getElementsByTagName("num-results")[0];
var mode = transport.responseXML.getElementsByTagName("mode")[0];
if (c && r) {
c.innerHTML = r.firstChild.nodeValue;
}
if (parseInt(mode.getAttribute("value")) == 2) {
Element.show('feed_archive_remove');
} else {
Element.hide('feed_archive_remove');
}
} });
} catch (e) {
exception_error("updateFeedBrowser", e);
}
}
function transport_error_check(transport) {
try {
@ -971,78 +831,6 @@ function hideAuxDlg() {
}
}
function feedBrowserSubscribe() {
try {
var selected = getSelectedFeedsFromBrowser();
var mode = document.forms['feed_browser'].mode;
mode = mode[mode.selectedIndex].value;
if (selected.length > 0) {
closeInfoBox();
notify_progress("Loading, please wait...", true);
var query = "?op=rpc&subop=massSubscribe&ids="+
param_escape(selected.toString()) + "&mode=" + param_escape(mode);
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
var nf = transport.responseXML.getElementsByTagName('num-feeds')[0];
var nf_value = nf.getAttribute("value");
notify_info(__("Subscribed to %d feed(s).").replace("%d", nf_value));
if (inPreferences()) {
updateFeedList();
} else {
setTimeout('updateFeedList(false, false)', 50);
}
} });
} else {
alert(__("No feeds are selected."));
}
} catch (e) {
exception_error("feedBrowserSubscribe", e);
}
}
function feedArchiveRemove() {
try {
var selected = getSelectedFeedsFromBrowser();
if (selected.length > 0) {
var pr = __("Remove selected feeds from the archive? Feeds with stored articles will not be removed.");
if (confirm(pr)) {
Element.show('feed_browser_spinner');
var query = "?op=rpc&subop=remarchived&ids=" +
param_escape(selected.toString());;
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
updateFeedBrowser();
} });
}
} else {
alert(__("No feeds are selected."));
}
} catch (e) {
exception_error("feedArchiveRemove", e);
}
}
function uploadIconHandler(rc) {
try {
@ -1162,8 +950,119 @@ function addLabel(select, callback) {
}
function quickAddFeed() {
displayDlg('quickAddFeed', '',
function () {$('feed_url').focus();});
try {
var query = "backend.php?op=dlg&id=quickAddFeed";
if (dijit.byId("feedAddDlg"))
dijit.byId("feedAddDlg").destroyRecursive();
var dialog = new dijit.Dialog({
id: "feedAddDlg",
title: __("Subscribe to Feed"),
style: "width: 600px",
execute: function() {
if (this.validate()) {
console.log(dojo.objectToQuery(this.attr('value')));
var feed_url = this.attr('value').feed;
notify_progress(__("Subscribing to feed..."), true);
new Ajax.Request("backend.php", {
parameters: dojo.objectToQuery(this.attr('value')),
onComplete: function(transport) {
try {
if (!transport.responseXML) {
console.log(transport.responseText);
alert(__("Server error while trying to subscribe to specified feed."));
return;
}
var result = transport.responseXML.getElementsByTagName('result')[0];
var rc = parseInt(result.getAttribute('code'));
notify('');
console.log("GOT RC: " + rc);
switch (rc) {
case 1:
dialog.hide();
notify_info(__("Subscribed to %s").replace("%s", feed_url));
if (inPreferences()) {
updateFeedList();
} else {
setTimeout('updateFeedList(false, false)', 50);
}
break;
case 2:
alert(__("Specified URL seems to be invalid."));
break;
case 3:
alert(__("Specified URL doesn't seem to contain any feeds."));
break;
case 4:
notify_progress("Searching for feed urls...", true);
new Ajax.Request("backend.php", {
parameters: 'op=rpc&subop=extractfeedurls&url=' + param_escape(feed_url),
onComplete: function(transport, dialog, feed_url) {
if (!transport.responseXML) {
console.log(transport.responseText);
alert(__("Server error while trying to query feed URLs."));
return;
}
notify('');
var result = transport.responseXML.getElementsByTagName('urls')[0];
var feeds = JSON.parse(result.firstChild.nodeValue);
console.log(transport.responseText);
var select = dijit.byId("feedDlg_feedContainerSelect");
while (select.getOptions().length > 0)
select.removeOption(0);
var count = 0;
for (var feedUrl in feeds) {
select.addOption({value: feedUrl, label: feeds[feedUrl]});
count++;
}
// if (count > 5) count = 5;
// select.size = count;
Effect.Appear('feedDlg_feedsContainer', {duration : 0.5});
}
});
break;
case 5:
alert(__("Couldn't download the specified URL."));
break;
case 0:
alert(__("You are already subscribed to this feed."));
break;
}
} catch (e) {
exception_error("subscribeToFeed", e);
}
} });
}
},
href: query});
dialog.show();
} catch (e) {
exception_error("quickAddFeed", e);
}
}
function quickAddFilter() {
@ -1239,8 +1138,8 @@ function unsubscribeFeed(feed_id, title) {
parameters: query,
onComplete: function(transport) {
closeInfoBox();
if (dijit.byId("feedEditDlg")) dijit.byId("feedEditDlg").hide();
if (inPreferences()) {
updateFeedList();
} else {
@ -1603,4 +1502,133 @@ function editFeed(feed, event) {
}
}
function feedBrowser() {
try {
var query = "backend.php?op=dlg&id=feedBrowser";
if (dijit.byId("feedAddDlg"))
dijit.byId("feedAddDlg").hide();
if (dijit.byId("feedBrowserDlg"))
dijit.byId("feedBrowserDlg").destroyRecursive();
var dialog = new dijit.Dialog({
id: "feedBrowserDlg",
title: __("More Feeds"),
style: "width: 600px",
getSelectedFeeds: function() {
var list = $$("#browseFeedList li[id*=FBROW]");
var selected = new Array();
list.each(function(child) {
var id = child.id.replace("FBROW-", "");
if (child.hasClassName('Selected')) {
selected.push(id);
}
});
return selected;
},
subscribe: function() {
var selected = this.getSelectedFeeds();
var mode = this.attr('value').mode;
if (selected.length > 0) {
dijit.byId("feedBrowserDlg").hide();
notify_progress("Loading, please wait...", true);
var query = "?op=rpc&subop=massSubscribe&ids="+
param_escape(selected.toString()) + "&mode=" + param_escape(mode);
console.log(query);
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
var nf = transport.responseXML.getElementsByTagName('num-feeds')[0];
var nf_value = nf.getAttribute("value");
notify_info(__("Subscribed to %d feed(s).").replace("%d", nf_value));
if (inPreferences()) {
updateFeedList();
} else {
setTimeout('updateFeedList(false, false)', 50);
}
} });
} else {
alert(__("No feeds are selected."));
}
},
update: function() {
var query = dojo.objectToQuery(dialog.attr('value'));
Element.show('feed_browser_spinner');
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
notify('');
Element.hide('feed_browser_spinner');
var c = $("browseFeedList");
var r = transport.responseXML.getElementsByTagName("content")[0];
var nr = transport.responseXML.getElementsByTagName("num-results")[0];
var mode = transport.responseXML.getElementsByTagName("mode")[0];
if (c && r) {
c.innerHTML = r.firstChild.nodeValue;
}
dojo.parser.parse("browseFeedList");
if (parseInt(mode.getAttribute("value")) == 2) {
Element.show(dijit.byId('feed_archive_remove').domNode);
} else {
Element.hide(dijit.byId('feed_archive_remove').domNode);
}
} });
},
removeFromArchive: function() {
var selected = this.getSelectedFeeds();
if (selected.length > 0) {
var pr = __("Remove selected feeds from the archive? Feeds with stored articles will not be removed.");
if (confirm(pr)) {
Element.show('feed_browser_spinner');
var query = "?op=rpc&subop=remarchived&ids=" +
param_escape(selected.toString());;
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
dialog.update();
} });
}
}
},
execute: function() {
if (this.validate()) {
this.subscribe();
}
},
href: query});
dialog.show();
} catch (e) {
exception_error("editFeed", e);
}
}

View File

@ -240,109 +240,101 @@
if ($id == "quickAddFeed") {
print "<title>".__('Subscribe to Feed')."</title>";
print "<content><![CDATA[";
print "<form id='feed_add_form' onsubmit='return false'>";
print "<input type=\"hidden\" name=\"op\" value=\"rpc\">";
print "<input type=\"hidden\" name=\"subop\" value=\"addfeed\">";
//print "<input type=\"hidden\" name=\"from\" value=\"tt-rss\">";
print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"rpc\">";
print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"subop\" value=\"addfeed\">";
print "<div class=\"dlgSec\">".__("Feed")."</div>";
print "<div class=\"dlgSecCont\">";
print __("URL:") . " ";
print "<input size=\"40\"
onkeypress=\"return filterCR(event, subscribeToFeed)\"
name=\"feed\" id=\"feed_url\">";
print "<input style=\"font-size : 16px; width : 20em;\"
placeHolder=\"".__("Feed URL")."\"
dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"feed\" id=\"feedDlg_feedUrl\">";
print "<br/>";
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print __('Place in category:') . " ";
print_feed_cat_select($link, "cat");
print_feed_cat_select($link, "cat", false, 'dojoType="dijit.form.Select"');
}
print "</div>";
print '<div id="fadd_feeds_container" style="display:none">
print '<div id="feedDlg_feedsContainer" style="display : none">
<div class="dlgSec">' . __('Available feeds') . '</div>
<div class="dlgSecCont">'
<div class="dlgSecCont">'.
'<select id="feedDlg_feedContainerSelect"
dojoType="dijit.form.Select" size="3">
<script type="dojo/method" event="onChange" args="value">
dijit.byId("feedDlg_feedUrl").attr("value", value);
</script>
</select>'.
'</div></div>';
. ' <select name="feed" id="faad_feeds_container_select" size="3"></select>'
. '</div></div>';
print "<div id='fadd_login_container' style='display:none'>
print "<div id='feedDlg_loginContainer' style='display : none'>
<div class=\"dlgSec\">".__("Authentication")."</div>
<div class=\"dlgSecCont\">".
__('Login:') . " <input name='login' size=\"20\"
onkeypress=\"return filterCR(event, subscribeToFeed)\"> ".
__('Password:') . "<input type='password'
name='pass' size=\"20\"
onkeypress=\"return filterCR(event, subscribeToFeed)\">
" <input dojoType=\"dijit.form.TextBox\" name='login'\"
placeHolder=\"".__("Login")."\"
style=\"width : 10em;\"> ".
" <input
placeHolder=\"".__("Password")."\"
dojoType=\"dijit.form.TextBox\" type='password'
style=\"width : 10em;\" name='pass'\">
</div></div>";
print "<div style=\"clear : both\">
<input type=\"checkbox\" id=\"fadd_login_check\"
onclick='checkboxToggleElement(this, \"fadd_login_container\")'>
<label for=\"fadd_login_check\">".
print "<div style=\"clear : both\">
<input type=\"checkbox\" dojoType=\"dijit.form.CheckBox\" id=\"feedDlg_loginCheck\"
onclick='checkboxToggleElement(this, \"feedDlg_loginContainer\")'>
<label for=\"feedDlg_loginCheck\">".
__('This feed requires authentication.')."</div>";
print "</form>";
print "<div class=\"dlgButtons\">
<button class=\"button\" id=\"fadd_submit_btn\"
onclick=\"return subscribeToFeed()\">".__('Subscribe')."</button>
<button onclick=\"return displayDlg('feedBrowser')\">".__('More feeds')."</button>
<button onclick=\"return closeInfoBox()\">".__('Cancel')."</button></div>";
print "]]></content>";
<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedAddDlg').execute()\">".__('Subscribe')."</button>
<button dojoType=\"dijit.form.Button\" onclick=\"return feedBrowser()\">".__('More feeds')."</button>
<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedAddDlg').hide()\">".__('Cancel')."</button>
</div>";
//return;
}
if ($id == "feedBrowser") {
print "<title>".__('Feed Browser')."</title>";
print "<content><![CDATA[";
$browser_search = db_escape_string($_REQUEST["search"]);
print "<form onsubmit='return false;' display='inline'
name='feed_browser' id='feed_browser'>";
# print "<form onsubmit='return false;' display='inline'
# name='feed_browser' id='feed_browser'>";
print "<input type=\"hidden\" name=\"op\" value=\"rpc\">";
print "<input type=\"hidden\" name=\"subop\" value=\"updateFeedBrowser\">";
print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"rpc\">";
print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"subop\" value=\"updateFeedBrowser\">";
print "<div dojoType=\"dijit.Toolbar\">
<div style='float : right'>
<img style='display : none'
id='feed_browser_spinner' src='".
theme_image($link, 'images/indicator_white.gif')."'>
<input name=\"search\" size=\"20\" type=\"search\"
onchange=\"javascript:updateFeedBrowser()\" value=\"$browser_search\">
<button onclick=\"javascript:updateFeedBrowser()\">".__('Search')."</button>
<input name=\"search\" dojoType=\"dijit.form.TextBox\" size=\"20\" type=\"search\"
onchange=\"dijit.byId('feedBrowserDlg').update()\" value=\"$browser_search\">
<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedBrowserDlg').update()\">".__('Search')."</button>
</div>";
print " <select name=\"mode\" onchange=\"updateFeedBrowser()\">
print " <select name=\"mode\" dojoType=\"dijit.form.Select\" onchange=\"dijit.byId('feedBrowserDlg').update()\">
<option value='1'>" . __('Popular feeds') . "</option>
<option value='2'>" . __('Feed archive') . "</option>
</select> ";
print __("limit:");
print " <select name=\"limit\" onchange='updateFeedBrowser()'>";
print " <select dojoType=\"dijit.form.Select\" name=\"limit\" onchange=\"dijit.byId('feedBrowserDlg').update()\">";
foreach (array(25, 50, 100, 200) as $l) {
$issel = ($l == $limit) ? "selected" : "";
print "<option $issel>$l</option>";
$issel = ($l == $limit) ? "selected=\"1\"" : "";
print "<option $issel value=\"$l\">$l</option>";
}
print "</select> ";
@ -356,12 +348,10 @@
print "</ul>";
print "<div align='center'>
<button onclick=\"feedBrowserSubscribe()\">".__('Subscribe')."</button>
<button style='display : none' id='feed_archive_remove' onclick=\"feedArchiveRemove()\">".__('Remove')."</button>
<button onclick=\"closeInfoBox()\" >".__('Cancel')."</button></div>";
<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedBrowserDlg').execute()\">".__('Subscribe')."</button>
<button dojoType=\"dijit.form.Button\" style='display : none' id='feed_archive_remove' onclick=\"dijit.byId('feedBrowserDlg').removeFromArchive()\">".__('Remove')."</button>
<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedBrowserDlg').hide()\" >".__('Cancel')."</button></div>";
print "]]></content>";
//return;
}
if ($id == "search") {

View File

@ -265,6 +265,7 @@
/* Title */
print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
placeHolder=\"".__("Feed Title")."\"
style=\"font-size : 16px; width: 20em\" name=\"title\" value=\"$title\">";
/* Feed URL */
@ -277,6 +278,7 @@
print __('URL:') . " ";
print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
placeHolder=\"".__("Feed URL")."\"
regExp='^(http|https)://.*' style=\"width : 20em\"
name=\"feed_url\" value=\"$feed_url\">";
@ -339,21 +341,23 @@
$auth_login = htmlspecialchars(db_fetch_result($result, 0, "auth_login"));
print "<table>";
# print "<table>";
print "<tr><td>" . __('Login:') . "</td><td>";
# print "<tr><td>" . __('Login:') . "</td><td>";
print "<input dojoType=\"dijit.form.TextBox\"
name=\"auth_login\" value=\"$auth_login\">";
placeHolder=\"".__("Login")."\"
name=\"auth_login\" value=\"$auth_login\"><br/>";
print "</tr><tr><td>" . __("Password:") . "</td><td>";
# print "</tr><tr><td>" . __("Password:") . "</td><td>";
$auth_pass = htmlspecialchars(db_fetch_result($result, 0, "auth_pass"));
print "<input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
placeHolder=\"".__("Password")."\"
value=\"$auth_pass\">";
print "</td></tr></table>";
# print "</td></tr></table>";
print "</div>";
print "<div class=\"dlgSec\">".__("Options")."</div>";
@ -613,7 +617,7 @@
<input type=\"submit\" class=\"button\"
onclick=\"return feedsEditSave()\" value=\"".__('Save')."\">
<input type='submit' class='button'
onclick=\"return feedEditCancel()\" value=\"".__('Cancel')."\">
onclick=\"return closeInfoBox()\" value=\"".__('Cancel')."\">
</div>";
print "]]></content></dlg>";
@ -1411,7 +1415,7 @@
$check_box = "<input onclick='toggleSelectListRow2(this)'
dojoType=\"dijit.form.CheckBox\"
type=\"checkbox\" id=\"FBCHK-" . $details["id"] . "\">";
type=\"checkbox\" \">";
$class = ($feedctr % 2) ? "even" : "odd";
@ -1449,8 +1453,8 @@
$feed_icon = "<img class=\"tinyFeedIcon\" src=\"images/blank_icon.gif\">";
}
$check_box = "<input onclick='toggleSelectListRow(this)' class='feedBrowseCB'
type=\"checkbox\" id=\"FBCHK-" . $line["id"] . "\">";
$check_box = "<input onclick='toggleSelectListRow2(this)' dojoType=\"dijit.form.CheckBox\"
type=\"checkbox\">";
$class = ($feedctr % 2) ? "even" : "odd";

View File

@ -147,38 +147,6 @@ function updateUsersList(sort_key) {
}
}
function addFeed() {
try {
var link = $("fadd_link");
if (link.value.length == 0) {
alert(__("Error: No feed URL given."));
} else if (!isValidURL(link.value)) {
alert(__("Error: Invalid feed URL."));
} else {
notify_progress("Adding feed...");
var query = "?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
param_escape(link.value);
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
feedlist_callback2(transport);
} });
link.value = "";
}
} catch (e) {
exception_error("addFeed", e);
}
}
function addPrefProfile() {
var profile = $("fadd_profile");
@ -1212,7 +1180,7 @@ function pref_hotkey_handler(e) {
}
if (keycode == 84 && shift_key) { // T
displayDlg('feedBrowser');
feedBrowser();
return false;
}
@ -1564,7 +1532,9 @@ function removeFilter(id, title) {
var ok = confirm(msg);
if (ok) {
dijit.byId("filterEditDlg").hide();
if (dijit.byId("filterEditDlg"))
dijit.byId("filterEditDlg").hide();
notify_progress("Removing filter...");

View File

@ -749,10 +749,6 @@ div.subscribers {
float : right;
}
input.feedBrowseCB {
margin-right : 1em;
}
div.browserDetails {
margin : 5px 5px 5px 5px;
padding : 5px;

View File

@ -283,6 +283,7 @@ function init() {
dojo.require("dijit.Toolbar");
dojo.require("dijit.ProgressBar");
dojo.require("dijit.Menu");
dojo.require("dojo.parser");
dojo.registerModulePath("fox", "../..");