summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/App.js40
-rw-r--r--js/Article.js1
-rw-r--r--js/CommonDialogs.js108
-rw-r--r--js/CommonFilters.js19
-rw-r--r--js/Feeds.js79
-rw-r--r--js/PrefFeedTree.js3
-rw-r--r--js/PrefFilterTree.js2
-rw-r--r--js/PrefHelpers.js164
-rw-r--r--js/PrefUsers.js1
9 files changed, 286 insertions, 131 deletions
diff --git a/js/App.js b/js/App.js
index db7797b75..6d7fd1c8b 100644
--- a/js/App.js
+++ b/js/App.js
@@ -16,6 +16,11 @@ const App = {
hotkey_actions: {},
is_prefs: false,
LABEL_BASE_INDEX: -1024,
+ FormFields: {
+ hidden: function(name, value) {
+ return `<input dojoType="dijit.form.TextBox" style="display : none" name="${name}" value="${value}"></input>`
+ }
+ },
Scrollable: {
scrollByPages: function (elem, page_offset) {
if (!elem) return;
@@ -49,6 +54,9 @@ const App = {
elem.offsetTop >= ctr.scrollTop;
}
},
+ dialogOf: function (widget) {
+ return dijit.getEnclosingWidget(widget.domNode.closest('.dijitDialog'));
+ },
label_to_feed_id: function(label) {
return this.LABEL_BASE_INDEX - 1 - Math.abs(label);
},
@@ -300,20 +308,15 @@ const App = {
}
},
helpDialog: function(topic) {
- if (dijit.byId("helpDlg"))
- dijit.byId("helpDlg").destroyRecursive();
-
- xhrPost("backend.php", {op: "backend", method: "help", topic: topic}, (transport) => {
- const dialog = new dijit.Dialog({
- id: "helpDlg",
- title: __("Help"),
- style: "width: 600px",
- content: transport.responseText,
- });
-
- dialog.show();
- });
- },
+ xhrPost("backend.php", {op: "backend", method: "help", topic: topic}, (transport) => {
+ const dialog = new dijit.Dialog({
+ title: __("Help"),
+ content: transport.responseText,
+ });
+
+ dialog.show();
+ });
+ },
displayDlg: function(title, id, param, callback) {
Notify.progress("Loading, please wait...", true);
@@ -329,7 +332,6 @@ const App = {
dialog = new dijit.Dialog({
title: title,
id: 'infoBox',
- style: "width: 600px",
onCancel: function () {
return true;
},
@@ -433,7 +435,7 @@ const App = {
console.log("RI:", k, "=>", v);
if (k == "daemon_is_running" && v != 1) {
- Notify.error("<span onclick=\"App.explainError(1)\">Update daemon is not running.</span>", true);
+ Notify.error("Update daemon is not running.", true);
return;
}
@@ -446,7 +448,7 @@ const App = {
}
if (k == "daemon_stamp_ok" && v != 1) {
- Notify.error("<span onclick=\"App.explainError(3)\">Update daemon is not updating feeds.</span>", true);
+ Notify.error("Update daemon is not updating feeds.", true);
return;
}
@@ -530,9 +532,6 @@ const App = {
this.initSecondStage();
},
- explainError: function(code) {
- return this.displayDlg(__("Error explained"), "explainError", code);
- },
Error: {
fatal: function (error, params) {
params = params || {};
@@ -599,7 +598,6 @@ const App = {
const dialog = new dijit.Dialog({
id: "exceptionDlg",
title: params.title || __("Unhandled exception"),
- style: "width: 600px",
content: content
});
diff --git a/js/Article.js b/js/Article.js
index a075e321f..538377f45 100644
--- a/js/Article.js
+++ b/js/Article.js
@@ -258,7 +258,6 @@ const Article = {
const dialog = new dijit.Dialog({
id: "editTagsDlg",
title: __("Edit article Tags"),
- style: "width: 600px",
content: transport.responseText,
execute: function () {
if (this.validate()) {
diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js
index b344967a7..b41065c63 100644
--- a/js/CommonDialogs.js
+++ b/js/CommonDialogs.js
@@ -87,7 +87,6 @@ const CommonDialogs = {
const dialog = new dijit.Dialog({
id: "feedAddDlg",
title: __("Subscribe to Feed"),
- style: "width: 600px",
content: transport.responseText,
show_error: function (msg) {
const elem = $("fadd_error_message");
@@ -199,7 +198,6 @@ const CommonDialogs = {
const dialog = new dijit.Dialog({
id: "errorFeedsDlg",
title: __("Feeds with update errors"),
- style: "width: 600px",
getSelectedFeeds: function () {
return Tables.getSelected("error-feeds-list");
},
@@ -309,7 +307,6 @@ const CommonDialogs = {
const dialog = new dijit.Dialog({
id: "feedEditDlg",
title: __("Edit Feed"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Notify.progress("Saving data...", true);
@@ -359,5 +356,108 @@ const CommonDialogs = {
});
}
return false;
- }
+ },
+ publishedOPML: function() {
+
+ Notify.progress("Loading, please wait...", true);
+
+ xhrJson("backend.php", {op: "pref-feeds", method: "getOPMLKey"}, (reply) => {
+ try {
+ if (dijit.byId("publicOPMLDlg"))
+ dijit.byId("publicOPMLDlg").destroyRecursive();
+
+ const dialog = new dijit.Dialog({
+ title: __("Public OPML URL"),
+ id: 'publicOPMLDlg',
+ onCancel: function () {
+ return true;
+ },
+ onExecute: function () {
+ return true;
+ },
+ onClose: function () {
+ return true;
+ },
+ content: `
+ <header>${__("Your Public OPML URL is:")}</header>
+ <section>
+ <div class='panel text-center'>
+ <a id='pub_opml_url' href="${App.escapeHtml(reply.link)}" target='_blank'>${reply.link}</a>
+ </div>
+ </section>
+ <footer class='text-center'>
+ <button dojoType='dijit.form.Button' onclick="return Helpers.OPML.changeKey()">
+ ${__('Generate new URL')}
+ </button>
+ <button dojoType='dijit.form.Button' type='submit' class='alt-primary'>
+ ${__('Close this window')}
+ </button>
+ </footer>
+ `
+ });
+
+ dialog.show();
+
+ Notify.close();
+
+ } catch (e) {
+ this.Error.report(e);
+ }
+ });
+ },
+ generatedFeed: function(feed, is_cat, rss_url) {
+
+ Notify.progress("Loading, please wait...", true);
+
+ xhrJson("backend.php", {op: "pref-feeds", method: "getFeedKey", id: feed, is_cat: is_cat}, (reply) => {
+ try {
+ if (dijit.byId("genFeedDlg"))
+ dijit.byId("genFeedDlg").destroyRecursive();
+
+ const feed_title = Feeds.getName(feed, is_cat);
+
+ const secret_url = rss_url + "&key=" + encodeURIComponent(reply.link);
+
+ const dialog = new dijit.Dialog({
+ title: __("Show as feed"),
+ id: 'genFeedDlg',
+ onCancel: function () {
+ return true;
+ },
+ onExecute: function () {
+ return true;
+ },
+ onClose: function () {
+ return true;
+ },
+ content: `
+ <header>${__("%s can be accessed via the following secret URL:").replace("%s", feed_title)}</header>
+ <section>
+ <div class='panel text-center'>
+ <a id='gen_feed_url' href="${App.escapeHtml(secret_url)}" target='_blank'>${secret_url}</a>
+ </div>
+ </section>
+ <footer>
+ <button dojoType='dijit.form.Button' style='float : left' class='alt-info'
+ onclick='window.open("https://tt-rss.org/wiki/GeneratedFeeds")'>
+ <i class='material-icons'>help</i> ${__("More info...")}</button>
+ <button dojoType='dijit.form.Button' onclick="return CommonDialogs.genUrlChangeKey('${feed}', '${is_cat}')">
+ ${__('Generate new URL')}
+ </button>
+ <button dojoType='dijit.form.Button' class='alt-primary' type='submit'>
+ ${__('Close this window')}
+ </button>
+ </footer>
+ `
+ });
+
+ dialog.show();
+
+ Notify.close();
+
+ } catch (e) {
+ this.Error.report(e);
+ }
+ });
+ },
};
diff --git a/js/CommonFilters.js b/js/CommonFilters.js
index 9676abe9e..61e6b2f95 100644
--- a/js/CommonFilters.js
+++ b/js/CommonFilters.js
@@ -130,7 +130,6 @@ const Filters = {
const rule_dlg = new dijit.Dialog({
id: "filterNewRuleDlg",
title: ruleStr ? __("Edit rule") : __("Add rule"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Filters.createNewRuleElement($("filterDlg_Matches"), replaceNode);
@@ -160,7 +159,6 @@ const Filters = {
const rule_dlg = new dijit.Dialog({
id: "filterNewActionDlg",
title: actionStr ? __("Edit action") : __("Add action"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Filters.createNewActionElement($("filterDlg_Actions"), replaceNode);
@@ -180,7 +178,6 @@ const Filters = {
const test_dlg = new dijit.Dialog({
id: "filterTestDlg",
title: "Test Filter",
- style: "width: 600px",
results: 0,
limit: 100,
max_offset: 10000,
@@ -251,10 +248,21 @@ const Filters = {
});
},
- href: "backend.php?op=pref-filters&method=testFilterDlg"
+ content: `
+ <div>
+ <img id='prefFilterLoadingIndicator' src='images/indicator_tiny.gif'>&nbsp;
+ <span id='prefFilterProgressMsg'>Looking for articles...</span>
+ </div>
+
+ <ul class='panel panel-scrollable list list-unstyled' id='prefFilterTestResultList'></ul>
+
+ <footer class='text-center'>
+ <button dojoType='dijit.form.Button' onclick="dijit.byId('filterTestDlg').hide()"><?php echo __('Close this window') ?></button>
+ </footer>
+ `
});
- dojo.connect(test_dlg, "onLoad", null, function (/* e */) {
+ dojo.connect(test_dlg, "onShow", null, function (/* e */) {
test_dlg.getTestResults(params, 0);
});
@@ -283,7 +291,6 @@ const Filters = {
const dialog = new dijit.Dialog({
id: "filterEditDlg",
title: __("Create Filter"),
- style: "width: 600px",
test: function () {
Filters.editFilterTest(dojo.formToObject("filter_new_form"));
},
diff --git a/js/Feeds.js b/js/Feeds.js
index ccb982cb3..45b8193e4 100644
--- a/js/Feeds.js
+++ b/js/Feeds.js
@@ -226,25 +226,64 @@ const Feeds = {
if (dijit.byId("defaultPasswordDlg"))
dijit.byId("defaultPasswordDlg").destroyRecursive();
- xhrPost("backend.php", {op: 'dlg', method: 'defaultpasswordwarning'}, (transport) => {
- const dialog = new dijit.Dialog({
- title: __("Your password is at default value"),
- content: transport.responseText,
- id: 'defaultPasswordDlg',
- style: "width: 600px",
- onCancel: function () {
- return true;
- },
- onExecute: function () {
- return true;
- },
- onClose: function () {
- return true;
- }
- });
+ const dialog = new dijit.Dialog({
+ title: __("Your password is at default value"),
+ content: `<div class='alert alert-error'>
+ ${__("You are using default tt-rss password. Please change it in the Preferences (Personal data / Authentication).")}
+ </div>
+
+ <footer class='text-center'>
+ <button dojoType='dijit.form.Button' class='alt-primary' onclick="document.location.href = 'prefs.php'">
+ ${__('Open Preferences')}
+ </button>
+ <button dojoType='dijit.form.Button' onclick="return dijit.byId('defaultPasswordDlg').hide()">
+ ${__('Close this window')}
+ </button>
+ </footer>`,
+ id: 'defaultPasswordDlg',
+ onCancel: function () {
+ return true;
+ },
+ onExecute: function () {
+ return true;
+ },
+ onClose: function () {
+ return true;
+ }
+ });
+
+ dialog.show();
+ }
- dialog.show();
+ if (dijit.byId("safeModeDlg"))
+ dijit.byId("safeModeDlg").destroyRecursive();
+
+ if (App.getInitParam("safe_mode")) {
+ const dialog = new dijit.Dialog({
+ title: __("Safe mode"),
+ content: `
+ <div class='alert alert-info'>
+ ${__('Tiny Tiny RSS is running in safe mode. All themes and plugins are disabled. You will need to log out and back in to disable it.')}
+ </div>
+ <footer class='text-center'>
+ <button dojoType='dijit.form.Button' type='submit' class='alt-primary'>
+ ${__('Close this window')}
+ </button>
+ </footer>
+ `,
+ id: 'safeModeDlg',
+ onCancel: function () {
+ return true;
+ },
+ onExecute: function () {
+ return true;
+ },
+ onClose: function () {
+ return true;
+ }
});
+
+ dialog.show();
}
// bw_limit disables timeout() so we request initial counters separately
@@ -555,19 +594,17 @@ const Feeds = {
return tree.model.store.getValue(nuf, 'bare_id');
},
search: function() {
- if (dijit.byId("searchDlg"))
- dijit.byId("searchDlg").destroyRecursive();
-
xhrPost("backend.php",
{op: "feeds", method: "search",
param: Feeds.getActive() + ":" + Feeds.activeIsCat()},
(transport) => {
+ if (dijit.byId("searchDlg"))
+ dijit.byId("searchDlg").destroyRecursive();
const dialog = new dijit.Dialog({
id: "searchDlg",
content: transport.responseText,
title: __("Search"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Feeds._search_query = this.attr('value');
diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js
index acd410a2c..4c8c25d0e 100644
--- a/js/PrefFeedTree.js
+++ b/js/PrefFeedTree.js
@@ -259,7 +259,6 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const dialog = new dijit.Dialog({
id: "feedEditDlg",
title: __("Edit Multiple Feeds"),
- style: "width: 600px",
getChildByName: function (name) {
let rv = null;
this.getChildren().each(
@@ -346,7 +345,6 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const dialog = new dijit.Dialog({
id: "batchSubDlg",
title: __("Batch subscribe"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Notify.progress(__("Subscribing to feeds..."), true);
@@ -372,7 +370,6 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const dialog = new dijit.Dialog({
id: "inactiveFeedsDlg",
title: __("Feeds without recent updates"),
- style: "width: 600px",
getSelectedFeeds: function () {
return Tables.getSelected("inactive-feeds-list");
},
diff --git a/js/PrefFilterTree.js b/js/PrefFilterTree.js
index b2041d182..a2e625bc1 100644
--- a/js/PrefFilterTree.js
+++ b/js/PrefFilterTree.js
@@ -147,8 +147,6 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const dialog = new dijit.Dialog({
id: "filterEditDlg",
title: __("Edit Filter"),
- style: "width: 600px",
-
test: function () {
Filters.editFilterTest(dojo.formToObject("filter_edit_form"));
},
diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js
index f9cb450e5..dd8fef5c6 100644
--- a/js/PrefHelpers.js
+++ b/js/PrefHelpers.js
@@ -1,6 +1,6 @@
'use strict';
-/* global __, dijit, dojo, Tables, xhrPost, Notify, xhrJson */
+/* global __, dijit, dojo, Tables, xhrPost, Notify, xhrJson, App */
const Helpers = {
AppPasswords: {
@@ -93,7 +93,6 @@ const Helpers = {
const dialog = new dijit.Dialog({
id: "profileEditDlg",
title: __("Settings Profiles"),
- style: "width: 600px",
getSelectedProfiles: function () {
return Tables.getSelected("pref-profiles-list");
},
@@ -119,22 +118,6 @@ const Helpers = {
alert(__("No profiles selected."));
}
},
- activateProfile: function () {
- const sel_rows = this.getSelectedProfiles();
-
- if (sel_rows.length == 1) {
- if (confirm(__("Activate selected profile?"))) {
- Notify.progress("Loading, please wait...");
-
- xhrPost("backend.php", {op: "rpc", method: "setprofile", id: sel_rows.toString()}, () => {
- window.location.reload();
- });
- }
-
- } else {
- alert(__("Please choose a profile to activate."));
- }
- },
addProfile: function () {
if (this.validate()) {
Notify.progress("Creating profile...", true);
@@ -149,8 +132,19 @@ const Helpers = {
}
},
execute: function () {
- if (this.validate()) {
- //
+ const sel_rows = this.getSelectedProfiles();
+
+ if (sel_rows.length == 1) {
+ if (confirm(__("Activate selected profile?"))) {
+ Notify.progress("Loading, please wait...");
+
+ xhrPost("backend.php", {op: "rpc", method: "setprofile", id: sel_rows.toString()}, () => {
+ window.location.reload();
+ });
+ }
+
+ } else {
+ alert(__("Please choose a profile to activate."));
}
},
href: query
@@ -159,33 +153,58 @@ const Helpers = {
dialog.show();
},
customizeCSS: function() {
- const query = "backend.php?op=pref-prefs&method=customizeCSS";
+ xhrJson("backend.php", {op: "pref-prefs", method: "customizeCSS"}, (reply) => {
- if (dijit.byId("cssEditDlg"))
- dijit.byId("cssEditDlg").destroyRecursive();
+ const dialog = new dijit.Dialog({
+ title: __("Customize stylesheet"),
+ apply: function() {
+ xhrPost("backend.php", this.attr('value'), () => {
+ new Effect.Appear("css_edit_apply_msg");
+ $("user_css_style").innerText = this.attr('value');
+ });
+ },
+ execute: function () {
+ Notify.progress('Saving data...', true);
- const dialog = new dijit.Dialog({
- id: "cssEditDlg",
- title: __("Customize stylesheet"),
- style: "width: 600px",
- apply: function() {
- xhrPost("backend.php", this.attr('value'), () => {
- new Effect.Appear("css_edit_apply_msg");
- $("user_css_style").innerText = this.attr('value');
- });
- },
- execute: function () {
- Notify.progress('Saving data...', true);
+ xhrPost("backend.php", this.attr('value'), () => {
+ window.location.reload();
+ });
+ },
+ content: `
+ <div class='alert alert-info'>
+ ${__("You can override colors, fonts and layout of your currently selected theme with custom CSS declarations here.")}
+ </div>
+
+ ${App.FormFields.hidden('op', 'rpc')}
+ ${App.FormFields.hidden('method', 'setpref')}
+ ${App.FormFields.hidden('key', 'USER_STYLESHEET')}
+
+ <div id='css_edit_apply_msg' style='display : none'>
+ <div class='alert alert-warning'>
+ ${__("User CSS has been applied, you might need to reload the page to see all changes.")}
+ </div>
+ </div>
+
+ <textarea class='panel user-css-editor' dojoType='dijit.form.SimpleTextarea'
+ style='font-size : 12px;' name='value'>${reply.value}</textarea>
+
+ <footer>
+ <button dojoType='dijit.form.Button' class='alt-success' onclick="App.dialogOf(this).apply()">
+ ${__('Apply')}
+ </button>
+ <button dojoType='dijit.form.Button' class='alt-primary' type='submit'>
+ ${__('Save and reload')}
+ </button>
+ <button dojoType='dijit.form.Button' onclick="App.dialogOf(this).hide()">
+ ${__('Cancel')}
+ </button>
+ </footer>
+ `
+ });
- xhrPost("backend.php", this.attr('value'), () => {
- window.location.reload();
- });
+ dialog.show();
- },
- href: query
});
-
- dialog.show();
},
confirmReset: function() {
if (confirm(__("Reset to defaults?"))) {
@@ -220,41 +239,42 @@ const Helpers = {
} else {
Notify.progress("Importing, please wait...", true);
- Element.show("upload_iframe");
-
- return true;
- }
- },
- onImportComplete: function(iframe) {
- if (!iframe.contentDocument.body.innerHTML) return false;
-
- Element.show(iframe);
-
- Notify.close();
+ const xhr = new XMLHttpRequest();
- if (dijit.byId('opmlImportDlg'))
- dijit.byId('opmlImportDlg').destroyRecursive();
+ xhr.open( 'POST', 'backend.php', true );
+ xhr.onload = function () {
+ Notify.close();
- const content = iframe.contentDocument.body.innerHTML;
+ const dialog = new dijit.Dialog({
+ title: __("OPML Import"),
+ onCancel: function () {
+ window.location.reload();
+ },
+ execute: function () {
+ window.location.reload();
+ },
+ content: `
+ <div class='alert alert-info'>
+ ${__("If you have imported labels and/or filters, you might need to reload preferences to see your new data.")}
+ </div>
+ <div class='panel panel-scrollable'>
+ ${xhr.responseText}
+ </div>
+ <footer class='text-center'>
+ <button dojoType='dijit.form.Button' type='submit' class='alt-primary'>
+ ${__('Close this window')}
+ </button>
+ </footer>
+ `
+ });
- const dialog = new dijit.Dialog({
- id: "opmlImportDlg",
- title: __("OPML Import"),
- style: "width: 600px",
- onCancel: function () {
- window.location.reload();
- },
- execute: function () {
- window.location.reload();
- },
- content: content
- });
+ dialog.show();
+ };
- dojo.connect(dialog, "onShow", function () {
- Element.hide(iframe);
- });
+ xhr.send(new FormData($("opml_import_form")));
- dialog.show();
+ return false;
+ }
},
export: function() {
console.log("export");
diff --git a/js/PrefUsers.js b/js/PrefUsers.js
index 2cebce6ef..a332a9140 100644
--- a/js/PrefUsers.js
+++ b/js/PrefUsers.js
@@ -36,7 +36,6 @@ const Users = {
const dialog = new dijit.Dialog({
id: "userEditDlg",
title: __("User Editor"),
- style: "width: 600px",
execute: function () {
if (this.validate()) {
Notify.progress("Saving data...", true);