Browse Source

Unsubscribe from feed through link or "#"

After importing old OPML files, you may discover that many feeds are
obsolete or uninteresting. You list the feeds entries and determine that
you want to unsubscribe. This needs three clicks (edit feed, delete,
confirm) and requires moving the mouse to hit the different targets.

This quickly becomes tiring, if you are up to possibly deleting hundreds
of feeds. One mediation, introduced in this commit, is to add an
unsubscribe link to each feed's entry listing view, and also adding a
keyboard shortcut.

The keyboard shortcut "#" is:
* longer than one keystroke (requires shift)
* hard to type by accident
* used in Google products (thanks for the hint @fguillot)

In an effort to try to reduce the number of accidental feed
unsubscriptions.
Carl Helmertz 7 years ago
parent
commit
15a11c3da9

+ 1 - 0
generate.go

@@ -194,6 +194,7 @@ func main() {
 			"ui/static/js/request_builder.js",
 			"ui/static/js/request_builder.js",
 			"ui/static/js/unread_counter_handler.js",
 			"ui/static/js/unread_counter_handler.js",
 			"ui/static/js/entry_handler.js",
 			"ui/static/js/entry_handler.js",
+			"ui/static/js/feed_handler.js",
 			"ui/static/js/confirm_handler.js",
 			"ui/static/js/confirm_handler.js",
 			"ui/static/js/menu_handler.js",
 			"ui/static/js/menu_handler.js",
 			"ui/static/js/modal_handler.js",
 			"ui/static/js/modal_handler.js",

+ 14 - 7
locale/translations.go

@@ -128,6 +128,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",
     "page.keyboard_shortcuts.save_article": "Artikel speichern",
     "page.keyboard_shortcuts.save_article": "Artikel speichern",
+    "page.keyboard_shortcuts.remove_feed": "Dieses Abonnement entfernen",
     "page.keyboard_shortcuts.go_to_search": "Fokus auf das Suchformular setzen",
     "page.keyboard_shortcuts.go_to_search": "Fokus auf das Suchformular setzen",
     "page.keyboard_shortcuts.close_modal": "Liste der Tastenkürzel schließen",
     "page.keyboard_shortcuts.close_modal": "Liste der Tastenkürzel schließen",
     "page.users.title": "Benutzer",
     "page.users.title": "Benutzer",
@@ -417,6 +418,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",
     "page.keyboard_shortcuts.save_article": "Save article",
     "page.keyboard_shortcuts.save_article": "Save article",
+    "page.keyboard_shortcuts.remove_feed": "Remove this feed",
     "page.keyboard_shortcuts.go_to_search": "Set focus on search form",
     "page.keyboard_shortcuts.go_to_search": "Set focus on search form",
     "page.keyboard_shortcuts.close_modal": "Close modal dialog",
     "page.keyboard_shortcuts.close_modal": "Close modal dialog",
     "page.users.title": "Users",
     "page.users.title": "Users",
@@ -686,6 +688,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",
     "page.keyboard_shortcuts.save_article": "Sauvegarder l'article",
     "page.keyboard_shortcuts.save_article": "Sauvegarder l'article",
+    "page.keyboard_shortcuts.remove_feed": "Supprimer ce flux",
     "page.keyboard_shortcuts.go_to_search": "Mettre le focus sur le champ de recherche",
     "page.keyboard_shortcuts.go_to_search": "Mettre le focus sur le champ de recherche",
     "page.keyboard_shortcuts.close_modal": "Fermer la boite de dialogue",
     "page.keyboard_shortcuts.close_modal": "Fermer la boite de dialogue",
     "page.users.title": "Utilisateurs",
     "page.users.title": "Utilisateurs",
@@ -976,6 +979,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",
     "page.keyboard_shortcuts.save_article": "Artikel opslaan",
     "page.keyboard_shortcuts.save_article": "Artikel opslaan",
+    "page.keyboard_shortcuts.remove_feed": "Verwijder deze feed",
     "page.keyboard_shortcuts.go_to_search": "Focus instellen op zoekformulier",
     "page.keyboard_shortcuts.go_to_search": "Focus instellen op zoekformulier",
     "page.keyboard_shortcuts.close_modal": "Sluit dialoogscherm",
     "page.keyboard_shortcuts.close_modal": "Sluit dialoogscherm",
     "page.users.title": "Gebruikers",
     "page.users.title": "Gebruikers",
@@ -1264,6 +1268,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",
     "page.keyboard_shortcuts.save_article": "Zapisz artykuł",
     "page.keyboard_shortcuts.save_article": "Zapisz artykuł",
+    "page.keyboard_shortcuts.remove_feed": "Usuń ten kanał",
     "page.keyboard_shortcuts.go_to_search": "Ustaw fokus na formularzu wyszukiwania",
     "page.keyboard_shortcuts.go_to_search": "Ustaw fokus na formularzu wyszukiwania",
     "page.keyboard_shortcuts.close_modal": "Zamknij listę skrótów klawiszowych",
     "page.keyboard_shortcuts.close_modal": "Zamknij listę skrótów klawiszowych",
     "page.users.title": "Użytkownicy",
     "page.users.title": "Użytkownicy",
@@ -1559,6 +1564,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",
     "page.keyboard_shortcuts.save_article": "Сохранить статью",
     "page.keyboard_shortcuts.save_article": "Сохранить статью",
+    "page.keyboard_shortcuts.remove_feed": "Удалить эту подписку",
     "page.keyboard_shortcuts.go_to_search": "Установить фокус в поисковой форме",
     "page.keyboard_shortcuts.go_to_search": "Установить фокус в поисковой форме",
     "page.keyboard_shortcuts.close_modal": "Закрыть модальный диалог",
     "page.keyboard_shortcuts.close_modal": "Закрыть модальный диалог",
     "page.users.title": "Пользователи",
     "page.users.title": "Пользователи",
@@ -1832,6 +1838,7 @@ var translations = map[string]string{
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",
     "page.keyboard_shortcuts.save_article": "保存文章",
     "page.keyboard_shortcuts.save_article": "保存文章",
+    "page.keyboard_shortcuts.remove_feed": "删除此Feed",
     "page.keyboard_shortcuts.go_to_search": "将重点放在搜索表单上",
     "page.keyboard_shortcuts.go_to_search": "将重点放在搜索表单上",
     "page.keyboard_shortcuts.close_modal": "关闭模态对话窗口",
     "page.keyboard_shortcuts.close_modal": "关闭模态对话窗口",
     "page.users.title": "用户",
     "page.users.title": "用户",
@@ -1991,11 +1998,11 @@ var translations = map[string]string{
 }
 }
 
 
 var translationsChecksums = map[string]string{
 var translationsChecksums = map[string]string{
-	"de_DE": "099dea24a10c4f842674db2ae44f99e99b9c880a6f83e3a42502603fa228fd32",
-	"en_US": "c23d1f16d1dbea72c1e1ba558c7a9c25e0ee8ffda420d50c998efe2fb4d9aa55",
-	"fr_FR": "a5afa30bb63cba48fe0c2114a5e0bcb62dee7f1df0eb5748524decd280c80970",
-	"nl_NL": "b1e548c2b21f013b1b54a07df7df7c06c776cbd7d26fc1fed288bd6970e99c3c",
-	"pl_PL": "8cb856dede8b4f75e4c6aeb0a45f09507c5010f782692e887aae357e99674218",
-	"ru_RU": "0544db0800811fc678521b2e9a7141380919b9ae259b3158524619bf120600ab",
-	"zh_CN": "92687fecfaaf74489714c52903987e7027d8c1cda45b60aa081f7b2165ccaed5",
+	"de_DE": "67d3a4bb4e3985ff62882ad0dc73dd86137e474d3e33d41162701a7228913b0a",
+	"en_US": "db7298b54554207287e2ba15de03646164774368dad54e00197f0162d541643f",
+	"fr_FR": "fb08492db1984800e5e095f0f784b9b430caa8172c7e0ecbbbc7de08f4adfa60",
+	"nl_NL": "3bdd3e0150878bc9c196300c7cacb30efd01b7b5df3926950c443d01084b9cee",
+	"pl_PL": "b81ddb5c5955b043c571701f84d9f3f0a75574e69240c458c7a42f3a20a5aa7e",
+	"ru_RU": "343393224e21437009e047deb728e4ed036646ed3e4df6101a6bc3cd084b9996",
+	"zh_CN": "74aefbf6be418ea198fa70d6ed5c7dd8bb3b7b112d9c3f90ebff41fba8c314a3",
 }
 }

+ 1 - 0
locale/translations/de_DE.json

@@ -123,6 +123,7 @@
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.download_content": "Vollständigen Inhalt herunterladen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Lesezeichen hinzufügen/entfernen",
     "page.keyboard_shortcuts.save_article": "Artikel speichern",
     "page.keyboard_shortcuts.save_article": "Artikel speichern",
+    "page.keyboard_shortcuts.remove_feed": "Dieses Abonnement entfernen",
     "page.keyboard_shortcuts.go_to_search": "Fokus auf das Suchformular setzen",
     "page.keyboard_shortcuts.go_to_search": "Fokus auf das Suchformular setzen",
     "page.keyboard_shortcuts.close_modal": "Liste der Tastenkürzel schließen",
     "page.keyboard_shortcuts.close_modal": "Liste der Tastenkürzel schließen",
     "page.users.title": "Benutzer",
     "page.users.title": "Benutzer",

+ 1 - 0
locale/translations/en_US.json

@@ -123,6 +123,7 @@
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.download_content": "Download original content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Toggle bookmark",
     "page.keyboard_shortcuts.save_article": "Save article",
     "page.keyboard_shortcuts.save_article": "Save article",
+    "page.keyboard_shortcuts.remove_feed": "Remove this feed",
     "page.keyboard_shortcuts.go_to_search": "Set focus on search form",
     "page.keyboard_shortcuts.go_to_search": "Set focus on search form",
     "page.keyboard_shortcuts.close_modal": "Close modal dialog",
     "page.keyboard_shortcuts.close_modal": "Close modal dialog",
     "page.users.title": "Users",
     "page.users.title": "Users",

+ 1 - 0
locale/translations/fr_FR.json

@@ -123,6 +123,7 @@
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.download_content": "Télécharger le contenu original",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ajouter/Enlever favoris",
     "page.keyboard_shortcuts.save_article": "Sauvegarder l'article",
     "page.keyboard_shortcuts.save_article": "Sauvegarder l'article",
+    "page.keyboard_shortcuts.remove_feed": "Supprimer ce flux",
     "page.keyboard_shortcuts.go_to_search": "Mettre le focus sur le champ de recherche",
     "page.keyboard_shortcuts.go_to_search": "Mettre le focus sur le champ de recherche",
     "page.keyboard_shortcuts.close_modal": "Fermer la boite de dialogue",
     "page.keyboard_shortcuts.close_modal": "Fermer la boite de dialogue",
     "page.users.title": "Utilisateurs",
     "page.users.title": "Utilisateurs",

+ 1 - 0
locale/translations/nl_NL.json

@@ -124,6 +124,7 @@
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.download_content": "Download originele content",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Ster toevoegen/weghalen",
     "page.keyboard_shortcuts.save_article": "Artikel opslaan",
     "page.keyboard_shortcuts.save_article": "Artikel opslaan",
+    "page.keyboard_shortcuts.remove_feed": "Verwijder deze feed",
     "page.keyboard_shortcuts.go_to_search": "Focus instellen op zoekformulier",
     "page.keyboard_shortcuts.go_to_search": "Focus instellen op zoekformulier",
     "page.keyboard_shortcuts.close_modal": "Sluit dialoogscherm",
     "page.keyboard_shortcuts.close_modal": "Sluit dialoogscherm",
     "page.users.title": "Gebruikers",
     "page.users.title": "Gebruikers",

+ 1 - 0
locale/translations/pl_PL.json

@@ -125,6 +125,7 @@
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.download_content": "Pobierz oryginalną zawartość",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Dodaj/usuń zakładki",
     "page.keyboard_shortcuts.save_article": "Zapisz artykuł",
     "page.keyboard_shortcuts.save_article": "Zapisz artykuł",
+    "page.keyboard_shortcuts.remove_feed": "Usuń ten kanał",
     "page.keyboard_shortcuts.go_to_search": "Ustaw fokus na formularzu wyszukiwania",
     "page.keyboard_shortcuts.go_to_search": "Ustaw fokus na formularzu wyszukiwania",
     "page.keyboard_shortcuts.close_modal": "Zamknij listę skrótów klawiszowych",
     "page.keyboard_shortcuts.close_modal": "Zamknij listę skrótów klawiszowych",
     "page.users.title": "Użytkownicy",
     "page.users.title": "Użytkownicy",

+ 1 - 0
locale/translations/ru_RU.json

@@ -125,6 +125,7 @@
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.download_content": "Загрузить оригинальное содержимое",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",
     "page.keyboard_shortcuts.toggle_bookmark_status": "Переключатель избранного",
     "page.keyboard_shortcuts.save_article": "Сохранить статью",
     "page.keyboard_shortcuts.save_article": "Сохранить статью",
+    "page.keyboard_shortcuts.remove_feed": "Удалить эту подписку",
     "page.keyboard_shortcuts.go_to_search": "Установить фокус в поисковой форме",
     "page.keyboard_shortcuts.go_to_search": "Установить фокус в поисковой форме",
     "page.keyboard_shortcuts.close_modal": "Закрыть модальный диалог",
     "page.keyboard_shortcuts.close_modal": "Закрыть модальный диалог",
     "page.users.title": "Пользователи",
     "page.users.title": "Пользователи",

+ 1 - 0
locale/translations/zh_CN.json

@@ -121,6 +121,7 @@
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.download_content": "下载原始内容",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",
     "page.keyboard_shortcuts.toggle_bookmark_status": "切换收藏状态",
     "page.keyboard_shortcuts.save_article": "保存文章",
     "page.keyboard_shortcuts.save_article": "保存文章",
+    "page.keyboard_shortcuts.remove_feed": "删除此Feed",
     "page.keyboard_shortcuts.go_to_search": "将重点放在搜索表单上",
     "page.keyboard_shortcuts.go_to_search": "将重点放在搜索表单上",
     "page.keyboard_shortcuts.close_modal": "关闭模态对话窗口",
     "page.keyboard_shortcuts.close_modal": "关闭模态对话窗口",
     "page.users.title": "用户",
     "page.users.title": "用户",

+ 2 - 1
template/common.go

@@ -208,6 +208,7 @@ var templateCommonMap = map[string]string{
                     <li>{{ t "page.keyboard_shortcuts.download_content" }} = <strong>d</strong></li>
                     <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.toggle_bookmark_status" }} = <strong>f</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</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.go_to_search" }} = <strong>/</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>
                 </ul>
                 </ul>
@@ -243,6 +244,6 @@ var templateCommonMap = map[string]string{
 var templateCommonMapChecksums = map[string]string{
 var templateCommonMapChecksums = map[string]string{
 	"entry_pagination": "4faa91e2eae150c5e4eab4d258e039dfdd413bab7602f0009360e6d52898e353",
 	"entry_pagination": "4faa91e2eae150c5e4eab4d258e039dfdd413bab7602f0009360e6d52898e353",
 	"item_meta":        "34deb081a054f2948ad808bdb2c8603d6ab00c58f2f50c4ead0b47ae092888eb",
 	"item_meta":        "34deb081a054f2948ad808bdb2c8603d6ab00c58f2f50c4ead0b47ae092888eb",
-	"layout":           "d1795cedbbc0fc6ec7a5e31039e10b8361b7a74bcca74d860f127ac159036ab6",
+	"layout":           "69ba8db45fde768cf71bab7dba60cece39968a185cec58850582dec11668efec",
 	"pagination":       "3386e90c6e1230311459e9a484629bc5d5bf39514a75ef2e73bbbc61142f7abb",
 	"pagination":       "3386e90c6e1230311459e9a484629bc5d5bf39514a75ef2e73bbbc61142f7abb",
 }
 }

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

@@ -134,6 +134,7 @@
                     <li>{{ t "page.keyboard_shortcuts.download_content" }} = <strong>d</strong></li>
                     <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.toggle_bookmark_status" }} = <strong>f</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.save_article" }} = <strong>s</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.go_to_search" }} = <strong>/</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>
                     <li>{{ t "page.keyboard_shortcuts.close_modal" }} = <strong>Esc</strong></li>
                 </ul>
                 </ul>

+ 2 - 1
template/html/edit_feed.html

@@ -92,6 +92,7 @@
     <div class="alert alert-error">
     <div class="alert alert-error">
         <a href="#"
         <a href="#"
             data-confirm="true"
             data-confirm="true"
+            data-action="remove-feed"
             data-label-question="{{ t "confirm.question" }}"
             data-label-question="{{ t "confirm.question" }}"
             data-label-yes="{{ t "confirm.yes" }}"
             data-label-yes="{{ t "confirm.yes" }}"
             data-label-no="{{ t "confirm.no" }}"
             data-label-no="{{ t "confirm.no" }}"
@@ -101,4 +102,4 @@
     </div>
     </div>
 {{ end }}
 {{ end }}
 
 
-{{ end }}
+{{ end }}

+ 11 - 0
template/html/feed_entries.html

@@ -15,6 +15,17 @@
         <li>
         <li>
             <a href="{{ route "editFeed" "feedID" .feed.ID }}">{{ t "menu.edit_feed" }}</a>
             <a href="{{ route "editFeed" "feedID" .feed.ID }}">{{ t "menu.edit_feed" }}</a>
         </li>
         </li>
+        <li>
+            <a href="#"
+                data-confirm="true"
+                data-action="remove-feed"
+                data-label-question="{{ t "confirm.question" }}"
+                data-label-yes="{{ t "confirm.yes" }}"
+                data-label-no="{{ t "confirm.no" }}"
+                data-label-loading="{{ t "confirm.loading" }}"
+                data-url="{{ route "removeFeed" "feedID" .feed.ID }}"
+                data-redirect-url="{{ route "feeds" }}">{{ t "action.remove_feed" }}</a>
+        </li>
     </ul>
     </ul>
 </section>
 </section>
 
 

+ 16 - 3
template/views.go

@@ -492,6 +492,7 @@ var templateViewsMap = map[string]string{
     <div class="alert alert-error">
     <div class="alert alert-error">
         <a href="#"
         <a href="#"
             data-confirm="true"
             data-confirm="true"
+            data-action="remove-feed"
             data-label-question="{{ t "confirm.question" }}"
             data-label-question="{{ t "confirm.question" }}"
             data-label-yes="{{ t "confirm.yes" }}"
             data-label-yes="{{ t "confirm.yes" }}"
             data-label-no="{{ t "confirm.no" }}"
             data-label-no="{{ t "confirm.no" }}"
@@ -501,7 +502,8 @@ var templateViewsMap = map[string]string{
     </div>
     </div>
 {{ end }}
 {{ end }}
 
 
-{{ end }}`,
+{{ end }}
+`,
 	"edit_user": `{{ define "title"}}{{ t "page.edit_user.title" .selected_user.Username }}{{ end }}
 	"edit_user": `{{ define "title"}}{{ t "page.edit_user.title" .selected_user.Username }}{{ end }}
 
 
 {{ define "content"}}
 {{ define "content"}}
@@ -696,6 +698,17 @@ var templateViewsMap = map[string]string{
         <li>
         <li>
             <a href="{{ route "editFeed" "feedID" .feed.ID }}">{{ t "menu.edit_feed" }}</a>
             <a href="{{ route "editFeed" "feedID" .feed.ID }}">{{ t "menu.edit_feed" }}</a>
         </li>
         </li>
+        <li>
+            <a href="#"
+                data-confirm="true"
+                data-action="remove-feed"
+                data-label-question="{{ t "confirm.question" }}"
+                data-label-yes="{{ t "confirm.yes" }}"
+                data-label-no="{{ t "confirm.no" }}"
+                data-label-loading="{{ t "confirm.loading" }}"
+                data-url="{{ route "removeFeed" "feedID" .feed.ID }}"
+                data-redirect-url="{{ route "feeds" }}">{{ t "action.remove_feed" }}</a>
+        </li>
     </ul>
     </ul>
 </section>
 </section>
 
 
@@ -1377,10 +1390,10 @@ var templateViewsMapChecksums = map[string]string{
 	"create_category":     "6b22b5ce51abf4e225e23a79f81be09a7fb90acb265e93a8faf9446dff74018d",
 	"create_category":     "6b22b5ce51abf4e225e23a79f81be09a7fb90acb265e93a8faf9446dff74018d",
 	"create_user":         "1e940be3afefc0a5c6273bbadcddc1e29811e9548e5227ac2adfe697ca5ce081",
 	"create_user":         "1e940be3afefc0a5c6273bbadcddc1e29811e9548e5227ac2adfe697ca5ce081",
 	"edit_category":       "daf073d2944a180ce5aaeb80b597eb69597a50dff55a9a1d6cf7938b48d768cb",
 	"edit_category":       "daf073d2944a180ce5aaeb80b597eb69597a50dff55a9a1d6cf7938b48d768cb",
-	"edit_feed":           "191c4c1f73e9f8d16938ec8cbd29afc7d7d1d17777394094bcf414ab198d9e51",
+	"edit_feed":           "ab30c31a4385a7b16c54baa78bdcb93a57181ed1c5018ce097d7eb50673bb995",
 	"edit_user":           "f4f99412ba771cfca2a2a42778b023b413c5494e9a287053ba8cf380c2865c5f",
 	"edit_user":           "f4f99412ba771cfca2a2a42778b023b413c5494e9a287053ba8cf380c2865c5f",
 	"entry":               "2ea9fee1ae5513ef1abb5923221c2ef1212e26d3bb651da66069ce8a336cbb7c",
 	"entry":               "2ea9fee1ae5513ef1abb5923221c2ef1212e26d3bb651da66069ce8a336cbb7c",
-	"feed_entries":        "814b58b106313d53f2929e5257c79e47a7e09d715e493f150d9dc3a8c97eaa4e",
+	"feed_entries":        "0f3d02d820475a3b0e165e10be2bf39fa5ab6a9dc5b0945c9ad886434e64e6ca",
 	"feeds":               "31acc253c547a6cce5710d72a6f6b3b396162ecd5e5af295b2cf47c1ff55bd06",
 	"feeds":               "31acc253c547a6cce5710d72a6f6b3b396162ecd5e5af295b2cf47c1ff55bd06",
 	"history_entries":     "b65ca1d85615caa7c314a33f1cb997aa3477a79e66b9894b2fd387271ad467d2",
 	"history_entries":     "b65ca1d85615caa7c314a33f1cb997aa3477a79e66b9894b2fd387271ad467d2",
 	"import":              "8349e47a783bb40d8e9248b4771656e5f006185e11079e1c4680dd52633420ed",
 	"import":              "8349e47a783bb40d8e9248b4771656e5f006185e11079e1c4680dd52633420ed",

File diff suppressed because it is too large
+ 2 - 0
ui/static/js.go


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

@@ -28,6 +28,7 @@ document.addEventListener("DOMContentLoaded", function() {
     keyboardHandler.on("d", () => navHandler.fetchOriginalContent());
     keyboardHandler.on("d", () => navHandler.fetchOriginalContent());
     keyboardHandler.on("f", () => navHandler.toggleBookmark());
     keyboardHandler.on("f", () => navHandler.toggleBookmark());
     keyboardHandler.on("?", () => navHandler.showKeyboardShortcuts());
     keyboardHandler.on("?", () => navHandler.showKeyboardShortcuts());
+    keyboardHandler.on("#", () => navHandler.unsubscribeFromFeed());
     keyboardHandler.on("/", (e) => navHandler.setFocusToSearchInput(e));
     keyboardHandler.on("/", (e) => navHandler.setFocusToSearchInput(e));
     keyboardHandler.on("Escape", () => ModalHandler.close());
     keyboardHandler.on("Escape", () => ModalHandler.close());
     keyboardHandler.listen();
     keyboardHandler.listen();

+ 7 - 0
ui/static/js/feed_handler.js

@@ -0,0 +1,7 @@
+class FeedHandler {
+    static unsubscribe(feedUrl, callback) {
+        let request = new RequestBuilder(feedUrl);
+        request.withCallback(callback);
+        request.execute();
+    }
+}

+ 14 - 0
ui/static/js/nav_handler.js

@@ -129,6 +129,20 @@ class NavHandler {
         }
         }
     }
     }
 
 
+    unsubscribeFromFeed() {
+        let unsubscribeLinks = document.querySelectorAll("[data-action=remove-feed]");
+        if (unsubscribeLinks.length === 1) {
+            let unsubscribeLink = unsubscribeLinks[0];
+            FeedHandler.unsubscribe(unsubscribeLink.dataset.url, () => {
+                if (unsubscribeLink.dataset.redirectUrl) {
+                    window.location.href = unsubscribeLink.dataset.redirectUrl;
+                } else {
+                    window.location.reload();
+                }
+            });
+        }
+    }
+
     /**
     /**
      * @param {string} page Page to redirect to.
      * @param {string} page Page to redirect to.
      * @param {boolean} fallbackSelf Refresh actual page if the page is not found.
      * @param {boolean} fallbackSelf Refresh actual page if the page is not found.

Some files were not shown because too many files changed in this diff