diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5c492350e7..c233fd9cc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@ You can also check [on GitHub](https://github.com/nextcloud/news/releases), the
# Unreleased
## [28.x.x]
### Changed
-
+- Add feature to Group starred Items per Feed
### Fixed
- Special characters may be displayed incorrectly when full text is enabled
diff --git a/appinfo/routes.php b/appinfo/routes.php
index a94d7a5026..a3c8bb1510 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -22,6 +22,7 @@
['name' => 'page#index', 'url' => '/folder/{folderId}', 'verb' => 'GET', 'postfix' => 'view.folderid'],
['name' => 'page#index', 'url' => '/recent', 'verb' => 'GET', 'postfix' => 'view.recent'],
['name' => 'page#index', 'url' => '/starred', 'verb' => 'GET', 'postfix' => 'view.starred'],
+['name' => 'page#index', 'url' => '/starred/{feedId}', 'verb' => 'GET', 'postfix' => 'view.starred.feed'],
['name' => 'page#index', 'url' => '/unread', 'verb' => 'GET', 'postfix' => 'view.unread'],
['name' => 'page#settings', 'url' => '/settings', 'verb' => 'GET'],
['name' => 'page#update_settings', 'url' => '/settings', 'verb' => 'PUT'],
diff --git a/lib/Controller/ItemController.php b/lib/Controller/ItemController.php
index e87ffaf5b9..62c4216163 100644
--- a/lib/Controller/ItemController.php
+++ b/lib/Controller/ItemController.php
@@ -155,7 +155,8 @@ public function index(
$limit,
$offset,
$oldestFirst,
- $search_items
+ $search_items,
+ $id
);
break;
}
diff --git a/lib/Db/Feed.php b/lib/Db/Feed.php
index 2f2b5f4046..e240de92d6 100644
--- a/lib/Db/Feed.php
+++ b/lib/Db/Feed.php
@@ -53,6 +53,8 @@ class Feed extends Entity implements IAPI, \JsonSerializable
protected $folderId;
/** @var int */
protected $unreadCount;
+ /** @var int */
+ protected $starredCount;
/** @var string|null */
protected $link = null;
/** @var bool */
@@ -322,6 +324,7 @@ public function jsonSerialize(): array
'added',
'folderId',
'unreadCount',
+ 'starredCount',
'link',
'preventUpdate',
'deletedAt',
diff --git a/lib/Db/FeedMapperV2.php b/lib/Db/FeedMapperV2.php
index 0ba04b86ca..5432c806ed 100644
--- a/lib/Db/FeedMapperV2.php
+++ b/lib/Db/FeedMapperV2.php
@@ -52,20 +52,36 @@ public function __construct(IDBConnection $db, Time $time)
public function findAllFromUser(string $userId, array $params = []): array
{
$builder = $this->db->getQueryBuilder();
- $builder->select('feeds.*', $builder->func()->count('items.id', 'unreadCount'))
+ $builder
+ ->select('feeds.*')
+ ->selectAlias(
+ $builder->createFunction('COUNT(DISTINCT items_unread.id)'),
+ 'unreadCount'
+ )
+ ->selectAlias(
+ $builder->createFunction('COUNT(DISTINCT items_starred.id)'),
+ 'starredCount'
+ )
->from(static::TABLE_NAME, 'feeds')
->leftJoin(
'feeds',
ItemMapperV2::TABLE_NAME,
- 'items',
- 'items.feed_id = feeds.id AND items.unread = :unread'
+ 'items_unread',
+ 'items_unread.feed_id = feeds.id AND items_unread.unread = :unread'
+ )
+ ->leftJoin(
+ 'feeds',
+ ItemMapperV2::TABLE_NAME,
+ 'items_starred',
+ 'items_starred.feed_id = feeds.id AND items_starred.starred = :starred'
)
->where('feeds.user_id = :user_id')
->andWhere('feeds.deleted_at = 0')
->groupBy('feeds.id')
->setParameter('unread', true, IQueryBuilder::PARAM_BOOL)
+ ->setParameter('starred', true, IQueryBuilder::PARAM_BOOL)
->setParameter('user_id', $userId)
- ->addOrderBy('title');
+ ->addOrderBy('feeds.title');
return $this->findEntities($builder);
}
diff --git a/lib/Db/ItemMapperV2.php b/lib/Db/ItemMapperV2.php
index 7c70c68798..f7341ca409 100644
--- a/lib/Db/ItemMapperV2.php
+++ b/lib/Db/ItemMapperV2.php
@@ -556,6 +556,7 @@ public function findAllFolder(
* @throws ServiceValidationException
*/
public function findAllItems(
+ int $feedId,
string $userId,
int $type,
int $limit,
@@ -588,6 +589,10 @@ public function findAllItems(
case ListType::STARRED:
$builder->andWhere('items.starred = :starred')
->setParameter('starred', true);
+ if ($feedId !== 0) {
+ $builder->andWhere('items.feed_id = :feedId')
+ ->setParameter('feedId', $feedId);
+ }
break;
case ListType::UNREAD:
$builder->andWhere('items.unread = :unread')
diff --git a/lib/Service/ItemServiceV2.php b/lib/Service/ItemServiceV2.php
index 7fbd5e82c5..ff79d7e623 100644
--- a/lib/Service/ItemServiceV2.php
+++ b/lib/Service/ItemServiceV2.php
@@ -388,8 +388,9 @@ public function findAllWithFilters(
int $limit,
int $offset,
bool $oldestFirst,
- array $search = []
+ array $search = [],
+ int $id = 0
): array {
- return $this->mapper->findAllItems($userId, $type, $limit, $offset, $oldestFirst, $search);
+ return $this->mapper->findAllItems($id, $userId, $type, $limit, $offset, $oldestFirst, $search);
}
}
diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue
index 121166eeb8..c7fd59fc1c 100644
--- a/src/components/Sidebar.vue
+++ b/src/components/Sidebar.vue
@@ -48,7 +48,27 @@
-
+
+
+
+
+
+
+
+
+
+
@@ -351,6 +371,7 @@ export default defineComponent({
polling: null,
uploadStatus: null,
selectedFile: null,
+ wasStarredVisited: false,
displayModeOptions: [
{
id: '0',
@@ -408,6 +429,10 @@ export default defineComponent({
return navItems
},
+ GroupedStars(): Array {
+ return this.$store.getters.feeds.filter((item: Feed) => item.starredCount !== 0)
+ },
+
loading: {
get() {
return this.$store.getters.loading
@@ -512,6 +537,17 @@ export default defineComponent({
}
},
},
+
+ // Watch route changes and set `wasStarredVisited`
+ $route: {
+ handler(to) {
+ if (to.name === this.ROUTES.STARRED && (to.params && to.params.feedId)) {
+ this.wasStarredVisited = true
+ }
+ },
+
+ immediate: true,
+ },
},
created() {
diff --git a/src/components/routes/Starred.vue b/src/components/routes/Starred.vue
index 442ea6317b..39a3154f34 100644
--- a/src/components/routes/Starred.vue
+++ b/src/components/routes/Starred.vue
@@ -1,14 +1,15 @@