diff --git a/internal/storage/feed.go b/internal/storage/feed.go index decb4638..464a0342 100644 --- a/internal/storage/feed.go +++ b/internal/storage/feed.go @@ -40,6 +40,14 @@ func (s *Storage) FeedExists(userID, feedID int64) bool { return result } +// CategoryFeedExists returns true if the given feed exists that belongs to the given category. +func (s *Storage) CategoryFeedExists(userID, categoryID, feedID int64) bool { + var result bool + query := `SELECT true FROM feeds WHERE user_id=$1 AND category_id=$2 AND id=$3` + s.db.QueryRow(query, userID, categoryID, feedID).Scan(&result) + return result +} + // FeedURLExists checks if feed URL already exists. func (s *Storage) FeedURLExists(userID int64, feedURL string) bool { var result bool diff --git a/internal/template/templates/common/feed_list.html b/internal/template/templates/common/feed_list.html index ee937949..e76cf624 100644 --- a/internal/template/templates/common/feed_list.html +++ b/internal/template/templates/common/feed_list.html @@ -66,7 +66,11 @@ data-label-yes="{{ t "confirm.yes" }}" data-label-no="{{ t "confirm.no" }}" data-label-loading="{{ t "confirm.loading" }}" - data-url="{{ route "removeFeed" "feedID" .ID }}">{{ icon "delete" }}{{ t "action.remove" }} + {{ if $.categoryID }} + data-url="{{ route "removeCategoryFeed" "categoryID" $.categoryID "feedID" .ID }}" + {{ else }} + data-url="{{ route "removeFeed" "feedID" .ID }}" + {{ end }}>{{ icon "delete" }}{{ t "action.remove" }} {{ if .UnreadCount }}
{{ t "alert.no_feed_in_category" }}
{{ else }} - {{ template "feed_list" dict "user" .user "feeds" .feeds "ParsingErrorCount" .ParsingErrorCount }} + {{ template "feed_list" dict "categoryID" .category.ID "user" .user "feeds" .feeds "ParsingErrorCount" .ParsingErrorCount }} {{ end }} {{ end }} diff --git a/internal/ui/category_remove_feed.go b/internal/ui/category_remove_feed.go new file mode 100644 index 00000000..bbea80a3 --- /dev/null +++ b/internal/ui/category_remove_feed.go @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package ui // import "miniflux.app/v2/internal/ui" + +import ( + "net/http" + + "miniflux.app/v2/internal/http/request" + "miniflux.app/v2/internal/http/response/html" + "miniflux.app/v2/internal/http/route" +) + +func (h *handler) removeCategoryFeed(w http.ResponseWriter, r *http.Request) { + feedID := request.RouteInt64Param(r, "feedID") + categoryID := request.RouteInt64Param(r, "categoryID") + + if !h.store.CategoryFeedExists(request.UserID(r), categoryID, feedID) { + html.NotFound(w, r) + return + } + + if err := h.store.RemoveFeed(request.UserID(r), feedID); err != nil { + html.ServerError(w, r, err) + return + } + + html.Redirect(w, r, route.Path(h.router, "categoryFeeds", "categoryID", categoryID)) +} diff --git a/internal/ui/ui.go b/internal/ui/ui.go index b0cbd57a..e1cb59a4 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -84,6 +84,7 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) { uiRouter.HandleFunc("/category/create", handler.showCreateCategoryPage).Name("createCategory").Methods(http.MethodGet) uiRouter.HandleFunc("/category/save", handler.saveCategory).Name("saveCategory").Methods(http.MethodPost) uiRouter.HandleFunc("/category/{categoryID}/feeds", handler.showCategoryFeedsPage).Name("categoryFeeds").Methods(http.MethodGet) + uiRouter.HandleFunc("/category/{categoryID}/feed/{feedID}/remove", handler.removeCategoryFeed).Name("removeCategoryFeed").Methods(http.MethodPost) uiRouter.HandleFunc("/category/{categoryID}/feeds/refresh", handler.refreshCategoryFeedsPage).Name("refreshCategoryFeedsPage").Methods(http.MethodGet) uiRouter.HandleFunc("/category/{categoryID}/entries", handler.showCategoryEntriesPage).Name("categoryEntries").Methods(http.MethodGet) uiRouter.HandleFunc("/category/{categoryID}/entries/refresh", handler.refreshCategoryEntriesPage).Name("refreshCategoryEntriesPage").Methods(http.MethodGet)