diff --git a/core/block/editor/subobject.go b/core/block/editor/subobject.go index 638c2827e..ac24ec8e6 100644 --- a/core/block/editor/subobject.go +++ b/core/block/editor/subobject.go @@ -72,15 +72,23 @@ func NewSubObject( } func (o *SubObject) Init(ctx *smartblock.InitContext) (err error) { - if o.forcedObjectType == "" { - return fmt.Errorf("missing forced object type") + objectType := o.forcedObjectType + if objectType == "" { + if len(ctx.ObjectTypeUrls) == 1 { + objectType, err = bundle.TypeKeyFromUrl(ctx.ObjectTypeUrls[0]) + if err != nil { + return err + } + } else { + return fmt.Errorf("missing object type for subobject") + } } if err = o.SmartBlock.Init(ctx); err != nil { return } - switch o.forcedObjectType { + switch objectType { case bundle.TypeKeyRelation: return o.initRelation(ctx.State) case bundle.TypeKeyObjectType: @@ -88,7 +96,7 @@ func (o *SubObject) Init(ctx *smartblock.InitContext) (err error) { case bundle.TypeKeyRelationOption: return o.initRelationOption(ctx.State) default: - return fmt.Errorf("unknown subobject type %s", o.forcedObjectType) + return fmt.Errorf("unknown subobject type %s", objectType) } } diff --git a/core/block/editor/template/template.go b/core/block/editor/template/template.go index d4564adc1..00b7cdc2e 100644 --- a/core/block/editor/template/template.go +++ b/core/block/editor/template/template.go @@ -597,7 +597,6 @@ var WithDataviewRequiredRelation = func(id string, key bundle.RelationKey) State } } if blockNeedToUpdate { - log.Errorf("add missing done relation for set") s.Set(simple.New(&model.Block{Content: &model.BlockContentOfDataview{Dataview: dv}, Id: id})) } } @@ -619,12 +618,12 @@ var WithDataviewID = func(id string, dataview model.BlockContentOfDataview, forc forceViews && len(dvBlock.Model().GetDataview().Relations) != len(dataview.Dataview.Relations) || forceViews && !pbtypes.DataviewViewsEqualSorted(dvBlock.Model().GetDataview().Views, dataview.Dataview.Views) { - log.With("thread", s.RootId()).With("name", pbtypes.GetString(s.Details(), "name")).Warnf("dataview needs to be migrated: %v, %v, %v, %v", - len(dvBlock.Model().GetDataview().Relations) == 0, - !slice.UnsortedEquals(dvBlock.Model().GetDataview().Source, dataview.Dataview.Source), - len(dvBlock.Model().GetDataview().Views) == 0, - forceViews && len(dvBlock.Model().GetDataview().Views[0].Filters) != len(dataview.Dataview.Views[0].Filters) || - forceViews && len(dvBlock.Model().GetDataview().Relations) != len(dataview.Dataview.Relations)) + /* log.With("thread", s.RootId()).With("name", pbtypes.GetString(s.Details(), "name")).Warnf("dataview needs to be migrated: %v, %v, %v, %v", + len(dvBlock.Model().GetDataview().Relations) == 0, + !slice.UnsortedEquals(dvBlock.Model().GetDataview().Source, dataview.Dataview.Source), + len(dvBlock.Model().GetDataview().Views) == 0, + forceViews && len(dvBlock.Model().GetDataview().Views[0].Filters) != len(dataview.Dataview.Views[0].Filters) || + forceViews && len(dvBlock.Model().GetDataview().Relations) != len(dataview.Dataview.Relations)) */ blockNeedToUpdate = true return false } diff --git a/core/block/object/creator.go b/core/block/object/creator.go index 3ecbf3741..fef7492cb 100644 --- a/core/block/object/creator.go +++ b/core/block/object/creator.go @@ -131,17 +131,23 @@ func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.S createState.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, pbtypes.Int64(time.Now().Unix())) createState.SetDetailAndBundledRelation(bundle.RelationKeyCreator, pbtypes.String(c.anytype.ProfileID())) - ev := &metrics.CreateObjectEvent{ - SetDetailsMs: time.Since(startTime).Milliseconds(), - } - ctx = context.WithValue(ctx, eventCreate, ev) var tid = thread.Undef - if raw := pbtypes.GetString(createState.CombinedDetails(), bundle.RelationKeyId.String()); raw != "" { - tid, err = thread.Decode(raw) + id = pbtypes.GetString(createState.CombinedDetails(), bundle.RelationKeyId.String()) + sbt, _ := coresb.SmartBlockTypeFromID(id) + if sbt == coresb.SmartBlockTypeSubObject { + return c.CreateSubObjectInWorkspace(createState.CombinedDetails(), workspaceID) + } else if id != "" { + tid, err = thread.Decode(id) if err != nil { log.Errorf("failed to decode thread id from the state: %s", err.Error()) } } + + ev := &metrics.CreateObjectEvent{ + SetDetailsMs: time.Since(startTime).Milliseconds(), + } + ctx = context.WithValue(ctx, eventCreate, ev) + csm, err := c.CreateObjectInWorkspace(ctx, workspaceID, tid, sbType) if err != nil { err = fmt.Errorf("anytype.CreateBlock error: %v", err) @@ -158,6 +164,7 @@ func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.S RelationIds: relationIds, } var sb smartblock.SmartBlock + if sb, err = c.objectFactory.InitObject(id, initCtx); err != nil { return id, nil, err } diff --git a/core/block/service.go b/core/block/service.go index 3fbb627bc..7ed276b85 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -88,7 +88,12 @@ type SmartblockOpener interface { func newOpenedBlock(sb smartblock.SmartBlock) *openedBlock { var ob = openedBlock{SmartBlock: sb} - if sb.Type() != model.SmartBlockType_Breadcrumbs { + if sb.Type() != model.SmartBlockType_Breadcrumbs && + sb.Type() != model.SmartBlockType_SubObject && + sb.Type() != model.SmartBlockType_Date && + sb.Type() != model.SmartBlockType_BundledRelation && + sb.Type() != model.SmartBlockType_BundledObjectType && + sb.Type() != model.SmartBlockType_BundledTemplate { // decode and store corresponding threadID for appropriate block if tid, err := thread.Decode(sb.Id()); err != nil { log.With("thread", sb.Id()).Warnf("can't restore thread ID: %v", err) diff --git a/pkg/lib/localstore/objectstore/objects.go b/pkg/lib/localstore/objectstore/objects.go index 4b3e2fd67..fbff618f4 100644 --- a/pkg/lib/localstore/objectstore/objects.go +++ b/pkg/lib/localstore/objectstore/objects.go @@ -4,13 +4,14 @@ import ( "context" "encoding/binary" "fmt" - "github.com/anytypeio/go-anytype-middleware/core/relation/relationutils" "runtime/debug" "strings" "sync" "time" - noctxds "github.com/anytypeio/go-anytype-middleware/pkg/lib/datastore/noctxds" + "github.com/anytypeio/go-anytype-middleware/core/relation/relationutils" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/datastore/noctxds" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" @@ -1903,17 +1904,6 @@ func (m *dsObjectStore) updateDetails(txn noctxds.Txn, id string, oldDetails *mo return nil } - for k, v := range newDetails.GetDetails().GetFields() { - // todo: remove null cleanup(should be done when receiving from client) - if _, isNull := v.GetKind().(*types.Value_NullValue); v == nil || isNull { - if slice.FindPos(bundle.LocalRelationsKeys, k) > -1 || slice.FindPos(bundle.DerivedRelationsKeys, k) > -1 { - log.Errorf("updateDetails %s: localDetail nulled %s: %s", id, k, pbtypes.Sprint(v)) - } else { - log.Warnf("updateDetails %s: detail nulled %s: %s", id, k, pbtypes.Sprint(v)) - } - } - } - diff := pbtypes.StructDiff(oldDetails.GetDetails(), newDetails.GetDetails()) log.Debugf("updateDetails %s: diff %s", id, pbtypes.Sprint(diff)) err = localstore.UpdateIndexesWithTxn(m, txn, oldDetails, newDetails, id) diff --git a/util/builtinobjects/builtinobjects.go b/util/builtinobjects/builtinobjects.go index e4ffe139b..31b7f38f7 100644 --- a/util/builtinobjects/builtinobjects.go +++ b/util/builtinobjects/builtinobjects.go @@ -4,6 +4,7 @@ import ( "archive/zip" "bytes" "context" + _ "embed" "fmt" "io" "io/ioutil" @@ -35,8 +36,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - - _ "embed" ) const CName = "builtinobjects" @@ -117,6 +116,11 @@ func (b *builtinObjects) inject(ctx context.Context) (err error) { if err != nil { return err } + if sbt == smartblock.SmartBlockTypeSubObject { + // preserve original id for subobjects, it makes no sense to replace them and also it breaks the grouping + b.idsMap[id] = id + continue + } tid, err := threads.ThreadCreateID(thread.AccessControlled, sbt) if err != nil { return err @@ -165,13 +169,16 @@ func (b *builtinObjects) createObject(ctx context.Context, rd io.ReadCloser) (er } m.Fields = &types.Struct{Fields: f} f["analyticsContext"] = pbtypes.String(analyticsContext) - f["analyticsOriginalId"] = pbtypes.String(oldId) + if f["analyticsOriginalId"] == nil { + // in case we already have analyticsOriginalId do not update it + f["analyticsOriginalId"] = pbtypes.String(oldId) + } st.Set(simple.New(m)) rels := relationutils.MigrateRelationModels(st.OldExtraRelations()) st.AddRelationLinks(rels...) - st.RemoveDetail(bundle.RelationKeyCreator.String(), bundle.RelationKeyLastModifiedBy.String()) + st.RemoveDetail(bundle.RelationKeyCreator.String(), bundle.RelationKeyLastModifiedBy.String(), bundle.RelationKeyLastOpenedDate.String(), bundle.RelationKeyLinks.String()) st.SetLocalDetail(bundle.RelationKeyCreator.String(), pbtypes.String(addr.AnytypeProfileId)) st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(addr.AnytypeProfileId)) st.InjectDerivedDetails() @@ -225,7 +232,7 @@ func (b *builtinObjects) createObject(ctx context.Context, rd io.ReadCloser) (er log.With("object", oldId).Errorf("failed to find relation %s: %s", k, err.Error()) continue } - if rel.Format != model.RelationFormat_object { + if rel.Format != model.RelationFormat_object && rel.Format != model.RelationFormat_tag && rel.Format != model.RelationFormat_status { continue } diff --git a/util/builtinobjects/data/bundled_objects.zip b/util/builtinobjects/data/bundled_objects.zip index 611eced57..ce8a7bb9d 100644 Binary files a/util/builtinobjects/data/bundled_objects.zip and b/util/builtinobjects/data/bundled_objects.zip differ diff --git a/util/pbtypes/pbtypes.go b/util/pbtypes/pbtypes.go index 32c09d7b3..f5806b0f0 100644 --- a/util/pbtypes/pbtypes.go +++ b/util/pbtypes/pbtypes.go @@ -66,7 +66,7 @@ func IntList(ints ...int) *types.Value { } func NilToNullWrapper(v *types.Value) *types.Value { - if v == nil { + if v == nil || v.Kind == nil { return Null() } return v @@ -204,7 +204,7 @@ func GetStringListValue(v *types.Value) []string { return nil } for _, v := range list.ListValue.Values { - if _, ok = v.GetKind().(*types.Value_StringValue); ok { + if str, ok := v.GetKind().(*types.Value_StringValue); ok && str.StringValue != "" { stringsSlice = append(stringsSlice, v.GetStringValue()) } }