From 3adfeb3b34eae57f7960ef6eac904a5f8d3aad25 Mon Sep 17 00:00:00 2001 From: Luca Bernstein Date: Thu, 29 Sep 2022 09:49:24 +0000 Subject: [PATCH] fix(namespaces): add list subscriptions (#1254) Add list subscriptions to namespaces call to enable frontend to show subscription state correctly. Resolves https://github.com/go-vikunja/frontend/issues/75 Reviewed-on: https://kolaente.dev/vikunja/api/pulls/1254 Reviewed-by: konrad Co-authored-by: Luca Bernstein Co-committed-by: Luca Bernstein --- pkg/models/list.go | 10 +++++++++ pkg/models/subscription.go | 45 +++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/pkg/models/list.go b/pkg/models/list.go index 822943f8d..17413e2c9 100644 --- a/pkg/models/list.go +++ b/pkg/models/list.go @@ -476,12 +476,22 @@ func addListDetails(s *xorm.Session, lists []*List, a web.Auth) (err error) { return err } + subscriptions, err := GetSubscriptions(s, SubscriptionEntityList, listIDs, a) + if err != nil { + log.Errorf("An error occurred while getting list subscriptions for a namespace item: %s", err.Error()) + subscriptions = make(map[int64]*Subscription) + } + for _, list := range lists { // Don't override the favorite state if it was already set from before (favorite saved filters do this) if list.IsFavorite { continue } list.IsFavorite = favs[list.ID] + + if subscription, exists := subscriptions[list.ID]; exists { + list.Subscription = subscription + } } if len(fileIDs) == 0 { diff --git a/pkg/models/subscription.go b/pkg/models/subscription.go index 284d63ecd..23d80376c 100644 --- a/pkg/models/subscription.go +++ b/pkg/models/subscription.go @@ -228,28 +228,53 @@ func getSubscriberCondForEntity(entityType SubscriptionEntityType, entityID int6 // that task, if there is none it will look for a subscription on the list the task belongs to and if that also // doesn't exist it will check for a subscription for the namespace the list is belonging to. func GetSubscription(s *xorm.Session, entityType SubscriptionEntityType, entityID int64, a web.Auth) (subscription *Subscription, err error) { + subs, err := GetSubscriptions(s, entityType, []int64{entityID}, a) + if err != nil || len(subs) == 0 { + return nil, err + } + if sub, exists := subs[entityID]; exists { + return sub, nil // Take exact match first, if available + } + for _, sub := range subs { + return sub, nil // For parents, take next available + } + return nil, nil +} + +// GetSubscriptions returns a map of subscriptions to a set of given entity IDs +func GetSubscriptions(s *xorm.Session, entityType SubscriptionEntityType, entityIDs []int64, a web.Auth) (listsToSubscriptions map[int64]*Subscription, err error) { u, is := a.(*user.User) if !is { return } - if err := entityType.validate(); err != nil { return nil, err } - subscription = &Subscription{} - cond := getSubscriberCondForEntity(entityType, entityID) - exists, err := s. + var entitiesFilter builder.Cond + for _, eID := range entityIDs { + if entitiesFilter == nil { + entitiesFilter = getSubscriberCondForEntity(entityType, eID) + continue + } + entitiesFilter = entitiesFilter.Or(getSubscriberCondForEntity(entityType, eID)) + } + + var subscriptions []*Subscription + err = s. Where("user_id = ?", u.ID). - And(cond). - Get(subscription) - if !exists { + And(entitiesFilter). + Find(&subscriptions) + if err != nil { return nil, err } - subscription.Entity = subscription.EntityType.String() - - return subscription, err + listsToSubscriptions = make(map[int64]*Subscription) + for _, sub := range subscriptions { + sub.Entity = sub.EntityType.String() + listsToSubscriptions[sub.EntityID] = sub + } + return listsToSubscriptions, nil } func getSubscribersForEntity(s *xorm.Session, entityType SubscriptionEntityType, entityID int64) (subscriptions []*Subscription, err error) {