render headline-specific toolbar on the client
This commit is contained in:
parent
37a81ba594
commit
a2e688fcb2
|
@ -16,103 +16,6 @@ class Feeds extends Handler_Protected {
|
|||
return array_search($method, $csrf_ignored) !== false;
|
||||
}
|
||||
|
||||
private function format_headline_subtoolbar($feed_site_url, $feed_title,
|
||||
$feed_id, $is_cat, $search,
|
||||
$error, $feed_last_updated) {
|
||||
|
||||
$cat_q = $is_cat ? "&is_cat=$is_cat" : "";
|
||||
|
||||
if ($search) {
|
||||
$search_q = "&q=$search";
|
||||
} else {
|
||||
$search_q = "";
|
||||
}
|
||||
|
||||
$reply = "";
|
||||
|
||||
$rss_link = htmlspecialchars(get_self_url_prefix() .
|
||||
"/public.php?op=rss&id=${feed_id}${cat_q}${search_q}");
|
||||
|
||||
$reply .= "<span class='left'>";
|
||||
|
||||
$reply .= "<a href=\"#\"
|
||||
title=\"".__("Show as feed")."\"
|
||||
onclick='CommonDialogs.generatedFeed(\"$feed_id\", \"$is_cat\", \"$rss_link\")'>
|
||||
<i class='icon-syndicate material-icons'>rss_feed</i></a>";
|
||||
|
||||
$reply .= "<span id='feed_title'>";
|
||||
|
||||
if ($feed_site_url) {
|
||||
$last_updated = T_sprintf("Last updated: %s", $feed_last_updated);
|
||||
|
||||
$reply .= "<a title=\"$last_updated\" target='_blank' href=\"$feed_site_url\">".
|
||||
truncate_string(strip_tags($feed_title), 30)."</a>";
|
||||
} else {
|
||||
$reply .= strip_tags($feed_title);
|
||||
}
|
||||
|
||||
if ($error)
|
||||
$reply .= " <i title=\"" . htmlspecialchars($error) . "\" class='material-icons icon-error'>error</i>";
|
||||
|
||||
$reply .= "</span>";
|
||||
$reply .= "<span id='feed_current_unread' style='display: none'></span>";
|
||||
$reply .= "</span>";
|
||||
|
||||
$reply .= "<span class=\"right\">";
|
||||
$reply .= "<span id='selected_prompt'></span>";
|
||||
$reply .= " ";
|
||||
|
||||
$reply .= "<div dojoType='fox.form.DropDownButton' title='".__('Select articles')."'>
|
||||
<span>".__("Select...")."</span>
|
||||
<div dojoType='dijit.Menu' style='display: none;'>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select(\"all\")'>".__('All')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select(\"unread\")'>".__('Unread')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select(\"invert\")'>".__('Invert')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select(\"none\")'>".__('None')."</div>
|
||||
<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionToggleUnread()'>".__('Toggle unread')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionToggleMarked()'>".__('Toggle starred')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionTogglePublished()'>".__('Toggle published')."</div>
|
||||
<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.catchupSelection()'>".__('Mark as read')."</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Article.selectionSetScore()'>".__('Set score')."</div>";
|
||||
|
||||
// TODO: move to mail plugin
|
||||
if (PluginHost::getInstance()->get_plugin("mail")) {
|
||||
$reply .= "<div dojoType='dijit.MenuItem' value='Plugins.Mail.send()'>".__('Forward by email')."</div>";
|
||||
}
|
||||
|
||||
// TODO: move to mailto plugin
|
||||
if (PluginHost::getInstance()->get_plugin("mailto")) {
|
||||
$reply .= "<div dojoType='dijit.MenuItem' value='Plugins.Mailto.send()'>".__('Forward by email')."</div>";
|
||||
}
|
||||
|
||||
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM,
|
||||
function ($result) use (&$reply) {
|
||||
$reply .= $result;
|
||||
},
|
||||
$feed_id, $is_cat);
|
||||
|
||||
if ($feed_id == 0 && !$is_cat) {
|
||||
$reply .= "<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' class='text-error' onclick='Headlines.deleteSelection()'>".__('Delete permanently')."</div>";
|
||||
}
|
||||
|
||||
$reply .= "</div>"; /* menu */
|
||||
|
||||
$reply .= "</div>"; /* dropdown */
|
||||
|
||||
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_HEADLINE_TOOLBAR_BUTTON,
|
||||
function ($result) use (&$reply) {
|
||||
$reply .= $result;
|
||||
},
|
||||
$feed_id, $is_cat);
|
||||
|
||||
$reply .= "</span>";
|
||||
|
||||
return $reply;
|
||||
}
|
||||
|
||||
private function format_headlines_list($feed, $method, $view_mode, $limit, $cat_view,
|
||||
$offset, $override_order = false, $include_children = false, $check_first_id = false,
|
||||
$skip_first_id_check = false, $order_by = false) {
|
||||
|
@ -222,10 +125,28 @@ class Feeds extends Handler_Protected {
|
|||
$reply['search_query'] = [$search, $search_language];
|
||||
$reply['vfeed_group_enabled'] = $vfeed_group_enabled;
|
||||
|
||||
$reply['toolbar'] = $this->format_headline_subtoolbar($feed_site_url,
|
||||
$feed_title,
|
||||
$feed, $cat_view, $search,
|
||||
$last_error, $last_updated);
|
||||
$plugin_menu_items = "";
|
||||
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM,
|
||||
function ($result) use (&$plugin_menu_items) {
|
||||
$plugin_menu_items .= $result;
|
||||
},
|
||||
$feed, $cat_view);
|
||||
|
||||
$plugin_buttons = "";
|
||||
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_HEADLINE_TOOLBAR_BUTTON,
|
||||
function ($result) use (&$plugin_buttons) {
|
||||
$plugin_buttons .= $result;
|
||||
},
|
||||
$feed, $cat_view);
|
||||
|
||||
$reply['toolbar'] = [
|
||||
'site_url' => $feed_site_url,
|
||||
'title' => truncate_string(strip_tags($feed_title), 30),
|
||||
'error' => $last_error,
|
||||
'last_updated' => $last_updated,
|
||||
'plugin_menu_items' => $plugin_menu_items,
|
||||
'plugin_buttons' => $plugin_buttons,
|
||||
];
|
||||
|
||||
$reply['content'] = [];
|
||||
|
||||
|
|
|
@ -1358,14 +1358,12 @@ class Pref_Feeds extends Handler_Protected {
|
|||
}
|
||||
|
||||
private function index_shared() {
|
||||
$rss_url = htmlspecialchars(get_self_url_prefix() .
|
||||
"/public.php?op=rss&id=-2&view-mode=all_articles");
|
||||
?>
|
||||
|
||||
<h3><?= __('Published articles can be subscribed by anyone who knows the following URL:') ?></h3>
|
||||
|
||||
<button dojoType='dijit.form.Button' class='alt-primary'
|
||||
onclick='CommonDialogs.generatedFeed(-2, false, "<?= $rss_url ?>", "<?= __("Published articles") ?>")'>
|
||||
onclick="CommonDialogs.generatedFeed(-2, false)">
|
||||
<?= __('Display URL') ?>
|
||||
</button>
|
||||
|
||||
|
@ -1603,11 +1601,23 @@ class Pref_Feeds extends Handler_Protected {
|
|||
print json_encode(["link" => $new_key]);
|
||||
}
|
||||
|
||||
function getFeedKey() {
|
||||
function getsharedurl() {
|
||||
$feed_id = clean($_REQUEST['id']);
|
||||
$is_cat = clean($_REQUEST['is_cat']);
|
||||
$is_cat = clean($_REQUEST['is_cat']) == "true";
|
||||
$search = clean($_REQUEST['search']);
|
||||
|
||||
print json_encode(["link" => Feeds::get_feed_access_key($feed_id, $is_cat, $_SESSION["uid"])]);
|
||||
$link = get_self_url_prefix() . "/public.php?" . http_build_query([
|
||||
'op' => 'rss',
|
||||
'id' => $feed_id,
|
||||
'is_cat' => (int)$is_cat,
|
||||
'q' => $search,
|
||||
'key' => Feeds::get_feed_access_key($feed_id, $is_cat, $_SESSION["uid"])
|
||||
]);
|
||||
|
||||
print json_encode([
|
||||
"title" => Feeds::getFeedTitle($feed_id, $is_cat),
|
||||
"link" => $link
|
||||
]);
|
||||
}
|
||||
|
||||
private function update_feed_access_key($feed_id, $is_cat, $owner_uid) {
|
||||
|
|
|
@ -176,9 +176,9 @@
|
|||
});
|
||||
?>
|
||||
|
||||
<form id="toolbar-headlines" action="" style="order : 10" onsubmit='return false'>
|
||||
<div id="toolbar-headlines" dojoType="fox.Toolbar" style="order : 10">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form id="toolbar-main" action="" style="order : 20" onsubmit='return false'>
|
||||
|
||||
|
|
|
@ -433,24 +433,19 @@ const CommonDialogs = {
|
|||
}
|
||||
});
|
||||
},
|
||||
generatedFeed: function(feed, is_cat, rss_url, feed_title) {
|
||||
generatedFeed: function(feed, is_cat, search = "") {
|
||||
|
||||
Notify.progress("Loading, please wait...", true);
|
||||
|
||||
xhrJson("backend.php", {op: "pref-feeds", method: "getFeedKey", id: feed, is_cat: is_cat}, (reply) => {
|
||||
xhrJson("backend.php", {op: "pref-feeds", method: "getsharedurl", id: feed, is_cat: is_cat, search: search}, (reply) => {
|
||||
try {
|
||||
if (!feed_title && typeof Feeds != "undefined")
|
||||
feed_title = Feeds.getName(feed, is_cat);
|
||||
|
||||
const secret_url = rss_url + "&key=" + encodeURIComponent(reply.link);
|
||||
|
||||
const dialog = new fox.SingleUseDialog({
|
||||
title: __("Show as feed"),
|
||||
content: `
|
||||
<header>${__("%s can be accessed via the following secret URL:").replace("%s", feed_title)}</header>
|
||||
<header>${__("%s can be accessed via the following secret URL:").replace("%s", App.escapeHtml(reply.title))}</header>
|
||||
<section>
|
||||
<div class='panel text-center'>
|
||||
<a id='gen_feed_url' href="${App.escapeHtml(secret_url)}" target='_blank'>${secret_url}</a>
|
||||
<a id='gen_feed_url' href="${App.escapeHtml(reply.link)}" target='_blank'>${App.escapeHtml(reply.link)}</a>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
|
|
|
@ -566,6 +566,58 @@ const Headlines = {
|
|||
}
|
||||
}
|
||||
},
|
||||
renderToolbar: function(headlines) {
|
||||
|
||||
const tb = headlines['toolbar'];
|
||||
const search_query = Feeds._search_query ? Feeds._search_query.query : "";
|
||||
const target = dijit.byId('toolbar-headlines');
|
||||
|
||||
target.attr('innerHTML',
|
||||
`
|
||||
<span class='left'>
|
||||
<a href="#" title="${__("Show as feed")}"
|
||||
onclick='CommonDialogs.generatedFeed("${headlines.id}", ${headlines.is_cat}, "${App.escapeHtml(search_query)}")'>
|
||||
<i class='icon-syndicate material-icons'>rss_feed</i>
|
||||
</a>
|
||||
${tb.site_url ?
|
||||
`<a class="feed_title" target="_blank" href="${App.escapeHtml(tb.site_url)}" title="${tb.last_updated}">${tb.title}</a>` :
|
||||
`<span class="feed_title">${tb.title}</span>`}
|
||||
${search_query ?
|
||||
`
|
||||
<span class='cancel_search'>(<a href='#' onclick='Feeds.cancelSearch()'>${__("Cancel search")}</a>)</span>
|
||||
` : ''}
|
||||
${tb.error ? `<i title="${App.escapeHtml(tb.error)}" class='material-icons icon-error'>error</i>` : ''}
|
||||
<span id='feed_current_unread' style='display: none'></span>
|
||||
</span>
|
||||
<span class='right'>
|
||||
<span id='selected_prompt'></span>
|
||||
<div dojoType='fox.form.DropDownButton' title='"${__('Select articles')}'>
|
||||
<span>${__("Select...")}</span>
|
||||
<div dojoType='dijit.Menu' style='display: none;'>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select("all")'>${__('All')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select("unread")'>${__('Unread')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select("invert")'>${__('Invert')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.select("none")'>${__('None')}</div>
|
||||
<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionToggleUnread()'>${__('Toggle unread')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionToggleMarked()'>${__('Toggle starred')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.selectionTogglePublished()'>${__('Toggle published')}</div>
|
||||
<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Headlines.catchupSelection()'>${__('Mark as read')}</div>
|
||||
<div dojoType='dijit.MenuItem' onclick='Article.selectionSetScore()'>${__('Set score')}</div>
|
||||
${tb.plugin_menu_items}
|
||||
${headlines.id === 0 && !headlines.is_cat ?
|
||||
`
|
||||
<div dojoType='dijit.MenuSeparator'></div>
|
||||
<div dojoType='dijit.MenuItem' class='text-error' onclick='Headlines.deleteSelection()'>${__('Delete permanently')}</div>
|
||||
` : ''}
|
||||
</div>
|
||||
${tb.plugin_buttons}
|
||||
</span>
|
||||
`);
|
||||
|
||||
dojo.parser.parse(target.domNode);
|
||||
},
|
||||
onLoaded: function (transport, offset, append) {
|
||||
const reply = App.handleRpcJson(transport);
|
||||
|
||||
|
@ -613,9 +665,11 @@ const Headlines = {
|
|||
this.headlines = [];
|
||||
this.vgroup_last_feed = undefined;
|
||||
|
||||
dojo.html.set($("toolbar-headlines"),
|
||||
/*dojo.html.set($("toolbar-headlines"),
|
||||
reply['headlines']['toolbar'],
|
||||
{parseContent: true});
|
||||
{parseContent: true});*/
|
||||
|
||||
Headlines.renderToolbar(reply['headlines']);
|
||||
|
||||
if (typeof reply['headlines']['content'] == 'string') {
|
||||
$("headlines-frame").innerHTML = reply['headlines']['content'];
|
||||
|
@ -646,11 +700,12 @@ const Headlines = {
|
|||
hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
|
||||
__("Click to open next unread feed.") + "</a>";
|
||||
|
||||
/*
|
||||
if (Feeds._search_query) {
|
||||
$("feed_title").innerHTML += "<span id='cancel_search'>" +
|
||||
" (<a href='#' onclick='Feeds.cancelSearch()'>" + __("Cancel search") + "</a>)" +
|
||||
"</span>";
|
||||
}
|
||||
} */
|
||||
|
||||
Headlines.updateCurrentUnread();
|
||||
|
||||
|
|
|
@ -15,12 +15,17 @@ class Mail extends Plugin {
|
|||
|
||||
$host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
|
||||
$host->add_hook($host::HOOK_PREFS_TAB, $this);
|
||||
$host->add_hook($host::HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM, $this);
|
||||
}
|
||||
|
||||
function get_js() {
|
||||
return file_get_contents(dirname(__FILE__) . "/mail.js");
|
||||
}
|
||||
|
||||
function hook_headline_toolbar_select_menu_item($feed_id, $is_cat) {
|
||||
return "<div dojoType='dijit.MenuItem' onclick='Plugins.Mail.send()'>".__('Forward by email')."</div>";
|
||||
}
|
||||
|
||||
function save() {
|
||||
$addresslist = $_POST["addresslist"];
|
||||
|
||||
|
|
|
@ -12,6 +12,11 @@ class MailTo extends Plugin {
|
|||
$this->host = $host;
|
||||
|
||||
$host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
|
||||
$host->add_hook($host::HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM, $this);
|
||||
}
|
||||
|
||||
function hook_headline_toolbar_select_menu_item($feed_id, $is_cat) {
|
||||
return "<div dojoType='dijit.MenuItem' onclick='Plugins.Mailto.send()'>".__('Forward by email')."</div>";
|
||||
}
|
||||
|
||||
function get_js() {
|
||||
|
|
|
@ -704,6 +704,8 @@ body.ttrss_main #toolbar-frame #toolbar i {
|
|||
margin: 0 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
padding-right: 4px;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
|
@ -713,7 +715,8 @@ body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left #feed_title {
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .feed_title,
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .cancel_search {
|
||||
margin-left: 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .right {
|
||||
|
|
|
@ -704,6 +704,8 @@ body.ttrss_main #toolbar-frame #toolbar i {
|
|||
margin: 0 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
padding-right: 4px;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
|
@ -713,7 +715,8 @@ body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left #feed_title {
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .feed_title,
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .cancel_search {
|
||||
margin-left: 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .right {
|
||||
|
|
|
@ -704,6 +704,8 @@ body.ttrss_main #toolbar-frame #toolbar i {
|
|||
margin: 0 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
padding-right: 4px;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
|
@ -713,7 +715,8 @@ body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left #feed_title {
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .feed_title,
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .cancel_search {
|
||||
margin-left: 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .right {
|
||||
|
|
|
@ -820,6 +820,8 @@ body.ttrss_main {
|
|||
}
|
||||
|
||||
#toolbar-headlines {
|
||||
font-size : 12px;
|
||||
background: transparent;
|
||||
padding-right : 4px;
|
||||
flex-grow : 2;
|
||||
display : flex;
|
||||
|
@ -829,7 +831,7 @@ body.ttrss_main {
|
|||
display : flex;
|
||||
align-items : center;
|
||||
|
||||
#feed_title {
|
||||
.feed_title, .cancel_search {
|
||||
margin-left : 4px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -705,6 +705,8 @@ body.ttrss_main #toolbar-frame #toolbar i {
|
|||
margin: 0 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
padding-right: 4px;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
|
@ -714,7 +716,8 @@ body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left #feed_title {
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .feed_title,
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .cancel_search {
|
||||
margin-left: 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .right {
|
||||
|
|
|
@ -705,6 +705,8 @@ body.ttrss_main #toolbar-frame #toolbar i {
|
|||
margin: 0 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
padding-right: 4px;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
|
@ -714,7 +716,8 @@ body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left #feed_title {
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .feed_title,
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .left .cancel_search {
|
||||
margin-left: 4px;
|
||||
}
|
||||
body.ttrss_main #toolbar-frame #toolbar #toolbar-headlines .right {
|
||||
|
|
Loading…
Reference in New Issue