ソースを参照

Adds keyboard shortcut for refreshing all feeds

- Binds the 'R' key to trigger a refresh in the background for all
feeds.
- Updates the locale, using the same description as the link in the
feeds page.

Co-authored-by: Vitor Pellegrino <pellegrino@linux.com>
Vitor Pellegrino 5 年 前
コミット
7fb0bdc9a5

+ 20 - 10
locale/translations.go

@@ -149,6 +149,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Kommentare öffnen",
     "page.keyboard_shortcuts.open_comments_same_window": "Öffne den Kommentare-Link in der aktuellen Registerkarte",
     "page.keyboard_shortcuts.toggle_read_status": "Gewählten Artikel als gelesen/ungelesen markieren",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Alle Abonnements im Hintergrund aktualisieren",
     "page.keyboard_shortcuts.mark_page_as_read": "Aktuelle Seite als gelesen markieren",
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",
@@ -484,6 +485,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Open comments link",
     "page.keyboard_shortcuts.open_comments_same_window": "Open comments link in current tab",
     "page.keyboard_shortcuts.toggle_read_status": "Toggle read/unread",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Refresh all feeds in the background",
     "page.keyboard_shortcuts.mark_page_as_read": "Mark current page as read",
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",
@@ -799,6 +801,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Abrir el enlace de comentarios",
     "page.keyboard_shortcuts.open_comments_same_window": "Abrir enlace de comentarios en la pestaña actual",
     "page.keyboard_shortcuts.toggle_read_status": "Marcar como leído o no leído",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Refrescar todas las fuentes en el fondo",
     "page.keyboard_shortcuts.mark_page_as_read": "Marcar pagína actual como leída",
     "page.keyboard_shortcuts.download_content": "Descargar el contento original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Agregar o quitar marcador",
@@ -1114,6 +1117,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Ouvrir le lien des commentaires",
     "page.keyboard_shortcuts.open_comments_same_window": "Ouvrir le lien des commentaires dans l'onglet en cours",
     "page.keyboard_shortcuts.toggle_read_status": "Basculer entre lu/non lu",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Actualiser les abonnements en arrière-plan",
     "page.keyboard_shortcuts.mark_page_as_read": "Marquer la page actuelle comme lu",
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",
@@ -1449,6 +1453,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Apri la pagina web dei commenti",
     "page.keyboard_shortcuts.open_comments_same_window": "Apri il link dei commenti nella scheda corrente",
     "page.keyboard_shortcuts.toggle_read_status": "Cambia lo stato di lettura (letto/da leggere)",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Aggiorna tutti i feed in background",
     "page.keyboard_shortcuts.mark_page_as_read": "Segna la pagina attuale come letta",
     "page.keyboard_shortcuts.download_content": "Scarica il contenuto integrale",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Aggiungi/rimuovi dai preferiti",
@@ -1764,6 +1769,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "コメントリンクを開く",
     "page.keyboard_shortcuts.open_comments_same_window": "現在のタブでコメントリンクを開く",
     "page.keyboard_shortcuts.toggle_read_status": "既読/未読 切り替え",
+    "page.keyboard_shortcuts.refresh_all_feeds": "全てのフィードをバックグラウンドで更新",
     "page.keyboard_shortcuts.mark_page_as_read": "現在のページを既読にする",
     "page.keyboard_shortcuts.download_content": "オリジナルの内容をダウンロード",
     "page.keyboard_shortcuts.toggle_bookmark_status": "星を付ける/外す",
@@ -2080,6 +2086,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Open opmerkingen link",
     "page.keyboard_shortcuts.open_comments_same_window": "Open de reactiekoppeling op het huidige tabblad",
     "page.keyboard_shortcuts.toggle_read_status": "Markeer gelezen/ongelezen",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Vernieuw alle feeds in de achtergrond",
     "page.keyboard_shortcuts.mark_page_as_read": "Markeer deze pagina als gelezen",
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",
@@ -2414,6 +2421,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "Otwórz link do komentarzy",
     "page.keyboard_shortcuts.open_comments_same_window": "Otwórz link do komentarzy w bieżącej karcie",
     "page.keyboard_shortcuts.toggle_read_status": "Oznacz jako przeczytane/nieprzeczytane",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Odśwież wszystkie subskrypcje w tle",
     "page.keyboard_shortcuts.mark_page_as_read": "Zaznacz aktualną stronę jako przeczytaną",
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",
@@ -2755,6 +2763,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments_same_window": "Открыть ссылку на комментарии в текущей вкладке",
     "page.keyboard_shortcuts.open_comments": "Открыть ссылку для комментариев",
     "page.keyboard_shortcuts.toggle_read_status": "Переключатель прочитанного",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Обновить все подписки в фоне",
     "page.keyboard_shortcuts.mark_page_as_read": "Отметить текущую страницу прочитанной",
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",
@@ -3074,6 +3083,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.open_comments": "打开评论链接",
     "page.keyboard_shortcuts.open_comments_same_window": "在当前标签页中打开评论链接",
     "page.keyboard_shortcuts.toggle_read_status": "切换已读/未读状态",
+    "page.keyboard_shortcuts.refresh_all_feeds": "在后台更新全部源",
     "page.keyboard_shortcuts.mark_page_as_read": "标记当前页已读",
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",
@@ -3259,14 +3269,14 @@ var translations = map[string]string{
 }
 
 var translationsChecksums = map[string]string{
-	"de_DE": "7c2c818451a72ac82bbdd0f27e7ea25454b8826f7032b219188644c8f20ffdb5",
-	"en_US": "82bae5216e33a188a0eae633620be6c124295484214f38e6364127684c07b7d8",
-	"es_ES": "f501a6e373bbef30175e6d944d6bed463a385341a41c54ba129dca261ff6a61d",
-	"fr_FR": "5fa9d2745b3420d0cf29a8aab0ecbbe43d885b3058988f0b9afa35a7f791a7c6",
-	"it_IT": "de975b7d55a7e83214bd7a8f6afd61bd1725feea61be848ebe062ceece4c4060",
-	"ja_JP": "96101b6f5b073284304f052548da30334c3488324022d46c889f5dd85f4ae1df",
-	"nl_NL": "dcb4a1e4c80479004d3e6ce639e7f1b48208b766754c4424d7be0a34d5682b19",
-	"pl_PL": "f920466805f2e40bd83e65a0396723c7a922ca73406e4a3fdb9e9228d944ce2d",
-	"ru_RU": "b3fdd388e001afe8878b1b58b41ccf7e2b593644b65c518366d60b09df374c8a",
-	"zh_CN": "058a8f98e6a682d6cd32b451cb83f440c9731eedd36090deac429ddf7570d00c",
+	"de_DE": "9dcd00605e1cce53d2e9b5009cf063d5b948022835c488e1ca540a9770a4d857",
+	"en_US": "144dcd9d68909ee2de603806dbcd378f2bee5b26789bff60dac295659c510497",
+	"es_ES": "f23e54a0f39ffd724d389fb4c5a5e274d1b4370bdbbb544efc113fc56489a6d7",
+	"fr_FR": "b9dd548782871317a2496e291b34646218084422d6120d50edc32ec4b69eaa93",
+	"it_IT": "bb7fd373d0e41b3942709d81213ade3e3a0ca0291d341453e21879dda53ef116",
+	"ja_JP": "0597183310bee313e70bf80dd2c31df732d8e7f55b02a6689132dc219a39298c",
+	"nl_NL": "c7de86bd209281f4e20847bae3a3c50c66f56655e16d7fed6bf8dd2844ae034b",
+	"pl_PL": "b5ea016c2ec6d37f81910d000ca43d732ebedb6bea0c862f94e4ac8787781dc2",
+	"ru_RU": "fa934cd06e362b782246199a84274aab0c6812437d07f4b112df02946a8c9cb4",
+	"zh_CN": "7c9069daf0bc611469404046f1902c2cb8f8b7c7dbb2708914b022f71e58d0f6",
 }

+ 1 - 0
locale/translations/de_DE.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "Kommentare öffnen",
     "page.keyboard_shortcuts.open_comments_same_window": "Öffne den Kommentare-Link in der aktuellen Registerkarte",
     "page.keyboard_shortcuts.toggle_read_status": "Gewählten Artikel als gelesen/ungelesen markieren",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Alle Abonnements im Hintergrund aktualisieren",
     "page.keyboard_shortcuts.mark_page_as_read": "Aktuelle Seite als gelesen markieren",
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",

+ 1 - 0
locale/translations/en_US.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "Open comments link",
     "page.keyboard_shortcuts.open_comments_same_window": "Open comments link in current tab",
     "page.keyboard_shortcuts.toggle_read_status": "Toggle read/unread",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Refresh all feeds in the background",
     "page.keyboard_shortcuts.mark_page_as_read": "Mark current page as read",
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",

+ 1 - 0
locale/translations/es_ES.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "Abrir el enlace de comentarios",
     "page.keyboard_shortcuts.open_comments_same_window": "Abrir enlace de comentarios en la pestaña actual",
     "page.keyboard_shortcuts.toggle_read_status": "Marcar como leído o no leído",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Refrescar todas las fuentes en el fondo",
     "page.keyboard_shortcuts.mark_page_as_read": "Marcar pagína actual como leída",
     "page.keyboard_shortcuts.download_content": "Descargar el contento original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Agregar o quitar marcador",

+ 1 - 0
locale/translations/fr_FR.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "Ouvrir le lien des commentaires",
     "page.keyboard_shortcuts.open_comments_same_window": "Ouvrir le lien des commentaires dans l'onglet en cours",
     "page.keyboard_shortcuts.toggle_read_status": "Basculer entre lu/non lu",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Actualiser les abonnements en arrière-plan",
     "page.keyboard_shortcuts.mark_page_as_read": "Marquer la page actuelle comme lu",
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",

+ 1 - 0
locale/translations/it_IT.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "Apri la pagina web dei commenti",
     "page.keyboard_shortcuts.open_comments_same_window": "Apri il link dei commenti nella scheda corrente",
     "page.keyboard_shortcuts.toggle_read_status": "Cambia lo stato di lettura (letto/da leggere)",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Aggiorna tutti i feed in background",
     "page.keyboard_shortcuts.mark_page_as_read": "Segna la pagina attuale come letta",
     "page.keyboard_shortcuts.download_content": "Scarica il contenuto integrale",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Aggiungi/rimuovi dai preferiti",

+ 1 - 0
locale/translations/ja_JP.json

@@ -144,6 +144,7 @@
     "page.keyboard_shortcuts.open_comments": "コメントリンクを開く",
     "page.keyboard_shortcuts.open_comments_same_window": "現在のタブでコメントリンクを開く",
     "page.keyboard_shortcuts.toggle_read_status": "既読/未読 切り替え",
+    "page.keyboard_shortcuts.refresh_all_feeds": "全てのフィードをバックグラウンドで更新",
     "page.keyboard_shortcuts.mark_page_as_read": "現在のページを既読にする",
     "page.keyboard_shortcuts.download_content": "オリジナルの内容をダウンロード",
     "page.keyboard_shortcuts.toggle_bookmark_status": "星を付ける/外す",

+ 1 - 0
locale/translations/nl_NL.json

@@ -145,6 +145,7 @@
     "page.keyboard_shortcuts.open_comments": "Open opmerkingen link",
     "page.keyboard_shortcuts.open_comments_same_window": "Open de reactiekoppeling op het huidige tabblad",
     "page.keyboard_shortcuts.toggle_read_status": "Markeer gelezen/ongelezen",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Vernieuw alle feeds in de achtergrond",
     "page.keyboard_shortcuts.mark_page_as_read": "Markeer deze pagina als gelezen",
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",

+ 1 - 0
locale/translations/pl_PL.json

@@ -146,6 +146,7 @@
     "page.keyboard_shortcuts.open_comments": "Otwórz link do komentarzy",
     "page.keyboard_shortcuts.open_comments_same_window": "Otwórz link do komentarzy w bieżącej karcie",
     "page.keyboard_shortcuts.toggle_read_status": "Oznacz jako przeczytane/nieprzeczytane",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Odśwież wszystkie subskrypcje w tle",
     "page.keyboard_shortcuts.mark_page_as_read": "Zaznacz aktualną stronę jako przeczytaną",
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",

+ 1 - 0
locale/translations/ru_RU.json

@@ -146,6 +146,7 @@
     "page.keyboard_shortcuts.open_comments_same_window": "Открыть ссылку на комментарии в текущей вкладке",
     "page.keyboard_shortcuts.open_comments": "Открыть ссылку для комментариев",
     "page.keyboard_shortcuts.toggle_read_status": "Переключатель прочитанного",
+    "page.keyboard_shortcuts.refresh_all_feeds": "Обновить все подписки в фоне",
     "page.keyboard_shortcuts.mark_page_as_read": "Отметить текущую страницу прочитанной",
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",

+ 1 - 0
locale/translations/zh_CN.json

@@ -142,6 +142,7 @@
     "page.keyboard_shortcuts.open_comments": "打开评论链接",
     "page.keyboard_shortcuts.open_comments_same_window": "在当前标签页中打开评论链接",
     "page.keyboard_shortcuts.toggle_read_status": "切换已读/未读状态",
+    "page.keyboard_shortcuts.refresh_all_feeds": "在后台更新全部源",
     "page.keyboard_shortcuts.mark_page_as_read": "标记当前页已读",
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",

+ 3 - 1
template/common.go

@@ -311,6 +311,7 @@ SOFTWARE.
 </head>
 <body
     data-entries-status-url="{{ route "updateEntriesStatus" }}"
+    data-refresh-all-feeds-url="{{ route "refreshAllFeeds" }}"
     {{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}>
     <div class="toast-wrap">
         <span class="toast-msg"></span>
@@ -414,6 +415,7 @@ SOFTWARE.
                     <li>{{ t "page.keyboard_shortcuts.download_content" }} = <strong>d</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.toggle_bookmark_status" }} = <strong>f</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</strong></li>
+                    <li>{{ t "page.keyboard_shortcuts.refresh_all_feeds" }} = <strong>R</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.remove_feed" }} = <strong>#</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.go_to_search" }} = <strong>/</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>
@@ -477,7 +479,7 @@ var templateCommonMapChecksums = map[string]string{
 	"feed_menu":        "318d8662dda5ca9dfc75b909c8461e79c86fb5082df1428f67aaf856f19f4b50",
 	"icons":            "f0d94c2cfa6655b44adaf97f0b95c52a9cff5c31f3a8829ad438e4db7114af7e",
 	"item_meta":        "a5b07cc6597e5c8f3ca849ee486acb3f16f062d8a1eaa47d2fb402ae6825b7ef",
-	"layout":           "a4ed0b69bf16342166358ca9c3cf23c27d61443eca2e5da9fa46ff7474afe55b",
+	"layout":           "91d2ab3f683a2ced5e9ce5cd04919e74b3e3f329a5eedcc60015b8d49ecb1b77",
 	"pagination":       "7b61288e86283c4cf0dc83bcbf8bf1c00c7cb29e60201c8c0b633b2450d2911f",
 	"settings_menu":    "e2b777630c0efdbc529800303c01d6744ed3af80ec505ac5a5b3f99c9b989156",
 }

+ 2 - 0
template/html/common/layout.html

@@ -44,6 +44,7 @@
 </head>
 <body
     data-entries-status-url="{{ route "updateEntriesStatus" }}"
+    data-refresh-all-feeds-url="{{ route "refreshAllFeeds" }}"
     {{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}>
     <div class="toast-wrap">
         <span class="toast-msg"></span>
@@ -147,6 +148,7 @@
                     <li>{{ t "page.keyboard_shortcuts.download_content" }} = <strong>d</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.toggle_bookmark_status" }} = <strong>f</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</strong></li>
+                    <li>{{ t "page.keyboard_shortcuts.refresh_all_feeds" }} = <strong>R</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.remove_feed" }} = <strong>#</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.go_to_search" }} = <strong>/</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>

+ 4 - 2
ui/static/js.go

@@ -38,6 +38,7 @@ isModifierKeyDown(event){return event.getModifierState("Control")||event.getModi
 getKey(event){const mapping={'Esc':'Escape','Up':'ArrowUp','Down':'ArrowDown','Left':'ArrowLeft','Right':'ArrowRight'};for(let key in mapping){if(mapping.hasOwnProperty(key)&&key===event.key){return mapping[key];}}
 return event.key;}}
 class RequestBuilder{constructor(url){this.callback=null;this.url=url;this.options={method:"POST",cache:"no-cache",credentials:"include",body:null,headers:new Headers({"Content-Type":"application/json","X-Csrf-Token":this.getCsrfToken()})};}
+withHttpMethod(method){this.options.method=method;return this;}
 withBody(body){this.options.body=JSON.stringify(body);return this;}
 withCallback(callback){this.callback=callback;return this;}
 getCsrfToken(){let element=document.querySelector("meta[name=X-CSRF-Token]");if(element!==null){return element.getAttribute("value");}
@@ -63,6 +64,7 @@ function handleEntryStatus(element){let toasting=!element;let currentEntry=findE
 function toggleEntryStatus(element,toasting){let entryID=parseInt(element.dataset.id,10);let link=element.querySelector("a[data-toggle-status]");let currentStatus=link.dataset.value;let newStatus=currentStatus==="read"?"unread":"read";updateEntriesStatus([entryID],newStatus);if(currentStatus==="read"){link.innerHTML='<span class="icon-label">'+link.dataset.labelRead+'</span>';link.dataset.value="unread";if(toasting){toast(link.dataset.toastUnread);}}else{link.innerHTML='<span class="icon-label">'+link.dataset.labelUnread+'</span>';link.dataset.value="read";if(toasting){toast(link.dataset.toastRead);}}
 if(element.classList.contains("item-status-"+currentStatus)){element.classList.remove("item-status-"+currentStatus);element.classList.add("item-status-"+newStatus);}}
 function markEntryAsRead(element){if(element.classList.contains("item-status-unread")){element.classList.remove("item-status-unread");element.classList.add("item-status-read");let entryID=parseInt(element.dataset.id,10);updateEntriesStatus([entryID],"read");}}
+function handleRefreshAllFeeds(){let url=document.body.dataset.refreshAllFeedsUrl;let request=new RequestBuilder(url);request.withCallback(()=>{window.location.reload();});request.withHttpMethod("GET");request.execute();}
 function updateEntriesStatus(entryIDs,status,callback){let url=document.body.dataset.entriesStatusUrl;let request=new RequestBuilder(url);request.withBody({entry_ids:entryIDs,status:status});request.withCallback(callback);request.execute();if(status==="read"){decrementUnreadCounter(1);}else{incrementUnreadCounter(1);}}
 function handleSaveEntry(element){let toasting=!element;let currentEntry=findEntry(element);if(currentEntry){saveEntry(currentEntry.querySelector("a[data-save-entry]"),toasting);}}
 function saveEntry(element,toasting){if(!element){return;}
@@ -102,7 +104,7 @@ function isListView(){return document.querySelector(".items")!==null;}
 function findEntry(element){if(isListView()){if(element){return DomHelper.findParent(element,"item");}else{return document.querySelector(".current-item");}}else{return document.querySelector(".entry");}}
 function handleConfirmationMessage(linkElement,callback){linkElement.style.display="none";let containerElement=linkElement.parentNode;let questionElement=document.createElement("span");let yesElement=document.createElement("a");yesElement.href="#";yesElement.appendChild(document.createTextNode(linkElement.dataset.labelYes));yesElement.onclick=(event)=>{event.preventDefault();let loadingElement=document.createElement("span");loadingElement.className="loading";loadingElement.appendChild(document.createTextNode(linkElement.dataset.labelLoading));questionElement.remove();containerElement.appendChild(loadingElement);callback(linkElement.dataset.url,linkElement.dataset.redirectUrl);};let noElement=document.createElement("a");noElement.href="#";noElement.appendChild(document.createTextNode(linkElement.dataset.labelNo));noElement.onclick=(event)=>{event.preventDefault();linkElement.style.display="inline";questionElement.remove();};questionElement.className="confirm";questionElement.appendChild(document.createTextNode(linkElement.dataset.labelQuestion+" "));questionElement.appendChild(yesElement);questionElement.appendChild(document.createTextNode(", "));questionElement.appendChild(noElement);containerElement.appendChild(questionElement);}
 function toast(msg){if(!msg)return;document.querySelector('.toast-wrap .toast-msg').innerHTML=msg;let toastWrapper=document.querySelector('.toast-wrap');toastWrapper.classList.remove('toastAnimate');setTimeout(function(){toastWrapper.classList.add('toastAnimate');},100);}
-document.addEventListener("DOMContentLoaded",function(){handleSubmitButtons();if(!document.querySelector("body[data-disable-keyboard-shortcuts=true]")){let keyboardHandler=new KeyboardHandler();keyboardHandler.on("g u",()=>goToPage("unread"));keyboardHandler.on("g b",()=>goToPage("starred"));keyboardHandler.on("g h",()=>goToPage("history"));keyboardHandler.on("g f",()=>goToFeedOrFeeds());keyboardHandler.on("g c",()=>goToPage("categories"));keyboardHandler.on("g s",()=>goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>goToPrevious());keyboardHandler.on("ArrowRight",()=>goToNext());keyboardHandler.on("k",()=>goToPrevious());keyboardHandler.on("p",()=>goToPrevious());keyboardHandler.on("j",()=>goToNext());keyboardHandler.on("n",()=>goToNext());keyboardHandler.on("h",()=>goToPage("previous"));keyboardHandler.on("l",()=>goToPage("next"));keyboardHandler.on("o",()=>openSelectedItem());keyboardHandler.on("v",()=>openOriginalLink());keyboardHandler.on("V",()=>openOriginalLink(true));keyboardHandler.on("c",()=>openCommentLink());keyboardHandler.on("C",()=>openCommentLink(true));keyboardHandler.on("m",()=>handleEntryStatus());keyboardHandler.on("A",()=>markPageAsRead());keyboardHandler.on("s",()=>handleSaveEntry());keyboardHandler.on("d",()=>handleFetchOriginalContent());keyboardHandler.on("f",()=>handleBookmark());keyboardHandler.on("?",()=>showKeyboardShortcuts());keyboardHandler.on("#",()=>unsubscribeFromFeed());keyboardHandler.on("/",(e)=>setFocusToSearchInput(e));keyboardHandler.on("Escape",()=>ModalHandler.close());keyboardHandler.listen();}
+document.addEventListener("DOMContentLoaded",function(){handleSubmitButtons();if(!document.querySelector("body[data-disable-keyboard-shortcuts=true]")){let keyboardHandler=new KeyboardHandler();keyboardHandler.on("g u",()=>goToPage("unread"));keyboardHandler.on("g b",()=>goToPage("starred"));keyboardHandler.on("g h",()=>goToPage("history"));keyboardHandler.on("g f",()=>goToFeedOrFeeds());keyboardHandler.on("g c",()=>goToPage("categories"));keyboardHandler.on("g s",()=>goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>goToPrevious());keyboardHandler.on("ArrowRight",()=>goToNext());keyboardHandler.on("k",()=>goToPrevious());keyboardHandler.on("p",()=>goToPrevious());keyboardHandler.on("j",()=>goToNext());keyboardHandler.on("n",()=>goToNext());keyboardHandler.on("h",()=>goToPage("previous"));keyboardHandler.on("l",()=>goToPage("next"));keyboardHandler.on("o",()=>openSelectedItem());keyboardHandler.on("v",()=>openOriginalLink());keyboardHandler.on("V",()=>openOriginalLink(true));keyboardHandler.on("c",()=>openCommentLink());keyboardHandler.on("C",()=>openCommentLink(true));keyboardHandler.on("m",()=>handleEntryStatus());keyboardHandler.on("A",()=>markPageAsRead());keyboardHandler.on("s",()=>handleSaveEntry());keyboardHandler.on("d",()=>handleFetchOriginalContent());keyboardHandler.on("f",()=>handleBookmark());keyboardHandler.on("R",()=>handleRefreshAllFeeds());keyboardHandler.on("?",()=>showKeyboardShortcuts());keyboardHandler.on("#",()=>unsubscribeFromFeed());keyboardHandler.on("/",(e)=>setFocusToSearchInput(e));keyboardHandler.on("Escape",()=>ModalHandler.close());keyboardHandler.listen();}
 let touchHandler=new TouchHandler();touchHandler.listen();onClick("a[data-save-entry]",(event)=>handleSaveEntry(event.target));onClick("a[data-toggle-bookmark]",(event)=>handleBookmark(event.target));onClick("a[data-fetch-content-entry]",()=>handleFetchOriginalContent());onClick("a[data-action=search]",(event)=>setFocusToSearchInput(event));onClick("a[data-action=markPageAsRead]",()=>handleConfirmationMessage(event.target,()=>markPageAsRead()));onClick("a[data-toggle-status]",(event)=>handleEntryStatus(event.target));onClick("a[data-confirm]",(event)=>handleConfirmationMessage(event.target,(url,redirectURL)=>{let request=new RequestBuilder(url);request.withCallback(()=>{if(redirectURL){window.location.href=redirectURL;}else{window.location.reload();}});request.execute();}));if(document.documentElement.clientWidth<600){onClick(".logo",()=>toggleMainMenu());onClick(".header nav li",(event)=>onClickMainMenuListItem(event));}
 if("serviceWorker"in navigator){let scriptElement=document.getElementById("service-worker-script");if(scriptElement){navigator.serviceWorker.register(scriptElement.src);}}
 window.addEventListener('beforeinstallprompt',(e)=>{e.preventDefault();let deferredPrompt=e;const promptHomeScreen=document.getElementById('prompt-home-screen');if(promptHomeScreen){promptHomeScreen.style.display="block";const btnAddToHomeScreen=document.getElementById('btn-add-to-home-screen');if(btnAddToHomeScreen){btnAddToHomeScreen.addEventListener('click',(e)=>{e.preventDefault();deferredPrompt.prompt();deferredPrompt.userChoice.then(()=>{deferredPrompt=null;promptHomeScreen.style.display="none";});});}}});});})();`,
@@ -110,6 +112,6 @@ window.addEventListener('beforeinstallprompt',(e)=>{e.preventDefault();let defer
 }
 
 var JavascriptsChecksums = map[string]string{
-	"app": "e7f953dd231bd59b239ba4c801366d1bc5d59233f085e4b0801e27c94e416416",
+	"app": "5b7b79ccbdaa1820052f5cf45f7dc92c58cb6362dffb01f8428db9bb82fa705b",
 	"sw":  "55fffa223919cc18572788fb9c62fccf92166c0eb5d3a1d6f91c31f24d020be9",
 }

+ 15 - 2
ui/static/js/app.js

@@ -167,11 +167,24 @@ function markEntryAsRead(element) {
     }
 }
 
+// Send the Ajax request to refresh all feeds in the background
+function handleRefreshAllFeeds() {
+    let url = document.body.dataset.refreshAllFeedsUrl;
+    let request = new RequestBuilder(url);
+
+    request.withCallback(() => {
+        window.location.reload();
+    });
+
+    request.withHttpMethod("GET");
+    request.execute();
+}
+
 // Send the Ajax request to change entries statuses.
 function updateEntriesStatus(entryIDs, status, callback) {
     let url = document.body.dataset.entriesStatusUrl;
     let request = new RequestBuilder(url);
-    request.withBody({ entry_ids: entryIDs, status: status });
+    request.withBody({entry_ids: entryIDs, status: status});
     request.withCallback(callback);
     request.execute();
 
@@ -296,7 +309,7 @@ function openOriginalLink(openLinkInCurrentTab) {
 
         let currentItem = document.querySelector(".current-item");
         // If we are not on the list of starred items, move to the next item
-        if (document.location.href != document.querySelector('a[data-page=starred]').href){
+        if (document.location.href != document.querySelector('a[data-page=starred]').href) {
             goToNextListItem();
         }
         markEntryAsRead(currentItem);

+ 2 - 1
ui/static/js/bootstrap.js

@@ -27,6 +27,7 @@ document.addEventListener("DOMContentLoaded", function () {
         keyboardHandler.on("s", () => handleSaveEntry());
         keyboardHandler.on("d", () => handleFetchOriginalContent());
         keyboardHandler.on("f", () => handleBookmark());
+        keyboardHandler.on("R", () => handleRefreshAllFeeds());
         keyboardHandler.on("?", () => showKeyboardShortcuts());
         keyboardHandler.on("#", () => unsubscribeFromFeed());
         keyboardHandler.on("/", (e) => setFocusToSearchInput(e));
@@ -91,5 +92,5 @@ document.addEventListener("DOMContentLoaded", function () {
                 });
             }
         }
-    });    
+    });
 });

+ 5 - 0
ui/static/js/request_builder.js

@@ -14,6 +14,11 @@ class RequestBuilder {
         };
     }
 
+    withHttpMethod(method) {
+        this.options.method = method;
+        return this;
+    }
+
     withBody(body) {
         this.options.body = JSON.stringify(body);
         return this;