1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-07 21:37:04 +09:00

Merge pull request #2158 from anyproto/go-5162-normalize-rec-rels-lists-on-state-build

GO-5162 Normalize recommended relations lists on state build
This commit is contained in:
Kirill Stonozhenko 2025-02-26 16:28:21 +01:00 committed by mcrakhman
parent 2bfc73668f
commit ef0955ed20
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
4 changed files with 88 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import (
"github.com/gogo/protobuf/types"
"github.com/anyproto/anytype-heart/core/block/simple"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
"github.com/anyproto/anytype-heart/util/slice"
@ -20,6 +21,7 @@ var (
func (s *State) Normalize(withLayouts bool) (err error) {
s.removeDuplicates()
s.normalizeDetails()
return s.normalize(withLayouts)
}
@ -392,3 +394,32 @@ func CleanupLayouts(s *State) (removedCount int) {
cleanup(s.RootId())
return
}
func (s *State) normalizeDetails() {
if s.ObjectTypeKey() == bundle.TypeKeyObjectType {
s.normalizeRecommendedRelations()
}
}
// normalizeRecommendedRelations normalizes recommended relations of Type on state build level, because
// these lists mustn't contain similar values, but could be updated by multiple clients independently
func (s *State) normalizeRecommendedRelations() {
details := s.details
if details == nil && s.parent != nil {
details = s.parent.details
}
if details == nil {
return
}
recRelations := details.GetStringList(bundle.RelationKeyRecommendedRelations)
recFeatRelations := details.GetStringList(bundle.RelationKeyRecommendedFeaturedRelations)
recHiddenRelations := details.GetStringList(bundle.RelationKeyRecommendedHiddenRelations)
recHiddenRelations = slice.RemoveN(recHiddenRelations, recFeatRelations...)
recHiddenRelations = slice.RemoveN(recHiddenRelations, recRelations...)
recRelations = slice.RemoveN(recRelations, recFeatRelations...)
details.SetStringList(bundle.RelationKeyRecommendedRelations, recRelations)
details.SetStringList(bundle.RelationKeyRecommendedHiddenRelations, recHiddenRelations)
}

View file

@ -13,6 +13,7 @@ import (
"golang.org/x/exp/slices"
"github.com/anyproto/anytype-heart/core/block/simple"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
@ -547,3 +548,26 @@ func countStringsLength(value *types.Value) (n int) {
}
return n
}
func TestNormalizeRecommendedRelations(t *testing.T) {
// given
s := NewDoc("root", nil).NewState().SetDetails(domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyRecommendedRelations: domain.StringList([]string{"s1", "sh", "sf", "sfh"}), // s stands for sidebar
bundle.RelationKeyRecommendedFeaturedRelations: domain.StringList([]string{"f1", "f2", "sfh", "fh", "sf"}),
bundle.RelationKeyRecommendedHiddenRelations: domain.StringList([]string{"sfh", "sh", "fh", "h1", "h2", "h3"}),
}))
child := s.NewState()
// when
s.normalizeRecommendedRelations()
child.normalizeRecommendedRelations()
// then
assert.Equal(t, []string{"s1", "sh"}, s.Details().GetStringList(bundle.RelationKeyRecommendedRelations))
assert.Equal(t, []string{"f1", "f2", "sfh", "fh", "sf"}, s.Details().GetStringList(bundle.RelationKeyRecommendedFeaturedRelations))
assert.Equal(t, []string{"h1", "h2", "h3"}, s.Details().GetStringList(bundle.RelationKeyRecommendedHiddenRelations))
assert.Equal(t, []string{"s1", "sh"}, child.Details().GetStringList(bundle.RelationKeyRecommendedRelations))
assert.Equal(t, []string{"f1", "f2", "sfh", "fh", "sf"}, child.Details().GetStringList(bundle.RelationKeyRecommendedFeaturedRelations))
assert.Equal(t, []string{"h1", "h2", "h3"}, child.Details().GetStringList(bundle.RelationKeyRecommendedHiddenRelations))
}

View file

@ -124,6 +124,32 @@ func RemoveIndex[T any](s []T, idx int) []T {
return s[:n]
}
// RemoveN is an analog of Remove function, but removing a range of values
func RemoveN[T comparable](s []T, vs ...T) []T {
var (
n int
found bool
sc = slices.Clone(s)
)
if len(vs) == 0 {
return sc
}
for _, x := range s {
found = false
for _, v := range vs {
if x == v {
found = true
break
}
}
if !found {
sc[n] = x
n++
}
}
return sc[:n]
}
func Filter[T any](vals []T, cond func(T) bool) []T {
var result = make([]T, 0, len(vals))
for i := range vals {

View file

@ -59,6 +59,13 @@ func Test_Remove(t *testing.T) {
assert.Equal(t, []string{"1", "2", "3"}, ids)
}
func Test_RemoveN(t *testing.T) {
var ids = []string{"1", "2", "3", "4", "1", "2", "0", "7"}
assert.Equal(t, []string{"2", "3", "4", "2", "0", "7"}, RemoveN(ids, "1"))
assert.Equal(t, []string{"3", "4", "0", "7"}, RemoveN(ids, "1", "2"))
assert.Equal(t, []string{"3", "0", "7"}, RemoveN(ids, "2", "4", "1"))
}
func TestHasPrefix(t *testing.T) {
assert.True(t, HasPrefix([]string{"1", "2"}, []string{"1", "2"}))
assert.True(t, HasPrefix([]string{"1", "2"}, []string{"1"}))