aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bug/comment.go9
-rw-r--r--bug/op_add_comment.go2
-rw-r--r--bug/op_create.go2
-rw-r--r--bug/op_create_test.go2
-rw-r--r--bug/op_edit_comment.go14
-rw-r--r--bug/time.go9
-rw-r--r--bug/timeline.go81
-rw-r--r--graphql/gqlgen.yml2
-rw-r--r--graphql/graph/gen_graph.go578
-rw-r--r--graphql/resolvers/root.go16
-rw-r--r--graphql/resolvers/timeline.go36
-rw-r--r--graphql/schema.graphql23
12 files changed, 695 insertions, 79 deletions
diff --git a/bug/comment.go b/bug/comment.go
index c7168275..db5cc45e 100644
--- a/bug/comment.go
+++ b/bug/comment.go
@@ -3,7 +3,6 @@ package bug
import (
"github.com/MichaelMure/git-bug/util/git"
"github.com/dustin/go-humanize"
- "time"
)
// Comment represent a comment in a Bug
@@ -14,16 +13,14 @@ type Comment struct {
// Creation time of the comment.
// Should be used only for human display, never for ordering as we can't rely on it in a distributed system.
- UnixTime int64
+ UnixTime Timestamp
}
// FormatTimeRel format the UnixTime of the comment for human consumption
func (c Comment) FormatTimeRel() string {
- t := time.Unix(c.UnixTime, 0)
- return humanize.Time(t)
+ return humanize.Time(c.UnixTime.Time())
}
func (c Comment) FormatTime() string {
- t := time.Unix(c.UnixTime, 0)
- return t.Format("Mon Jan 2 15:04:05 2006 +0200")
+ return c.UnixTime.Time().Format("Mon Jan 2 15:04:05 2006 +0200")
}
diff --git a/bug/op_add_comment.go b/bug/op_add_comment.go
index 4594ba70..7f8b8b5b 100644
--- a/bug/op_add_comment.go
+++ b/bug/op_add_comment.go
@@ -30,7 +30,7 @@ func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
Message: op.Message,
Author: op.Author,
Files: op.Files,
- UnixTime: op.UnixTime,
+ UnixTime: Timestamp(op.UnixTime),
}
snapshot.Comments = append(snapshot.Comments, comment)
diff --git a/bug/op_create.go b/bug/op_create.go
index 5c41eb7c..0553137f 100644
--- a/bug/op_create.go
+++ b/bug/op_create.go
@@ -32,7 +32,7 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) {
comment := Comment{
Message: op.Message,
Author: op.Author,
- UnixTime: op.UnixTime,
+ UnixTime: Timestamp(op.UnixTime),
}
snapshot.Comments = []Comment{comment}
diff --git a/bug/op_create_test.go b/bug/op_create_test.go
index e9a36cf8..f27f6ee0 100644
--- a/bug/op_create_test.go
+++ b/bug/op_create_test.go
@@ -26,7 +26,7 @@ func TestCreate(t *testing.T) {
t.Fatal(err)
}
- comment := Comment{Author: rene, Message: "message", UnixTime: create.UnixTime}
+ comment := Comment{Author: rene, Message: "message", UnixTime: Timestamp(create.UnixTime)}
expected := Snapshot{
Title: "title",
diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go
index c6cfab2b..cb4a2216 100644
--- a/bug/op_edit_comment.go
+++ b/bug/op_edit_comment.go
@@ -57,18 +57,20 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) {
return
}
+ comment := Comment{
+ Message: op.Message,
+ Files: op.Files,
+ UnixTime: Timestamp(op.UnixTime),
+ }
+
switch target.(type) {
case *CreateTimelineItem:
item := target.(*CreateTimelineItem)
- newComment := item.LastState()
- newComment.Message = op.Message
- item.History = append(item.History, newComment)
+ item.Append(comment)
case *CommentTimelineItem:
item := target.(*CommentTimelineItem)
- newComment := item.LastState()
- newComment.Message = op.Message
- item.History = append(item.History, newComment)
+ item.Append(comment)
}
snapshot.Comments[commentIndex].Message = op.Message
diff --git a/bug/time.go b/bug/time.go
new file mode 100644
index 00000000..a085e8e9
--- /dev/null
+++ b/bug/time.go
@@ -0,0 +1,9 @@
+package bug
+
+import "time"
+
+type Timestamp int64
+
+func (t Timestamp) Time() time.Time {
+ return time.Unix(int64(t), 0)
+}
diff --git a/bug/timeline.go b/bug/timeline.go
index 0f79958b..d734e18b 100644
--- a/bug/timeline.go
+++ b/bug/timeline.go
@@ -1,50 +1,67 @@
package bug
-import "github.com/MichaelMure/git-bug/util/git"
+import (
+ "github.com/MichaelMure/git-bug/util/git"
+)
type TimelineItem interface {
// Hash return the hash of the item
Hash() (git.Hash, error)
}
+type CommentHistoryStep struct {
+ Message string
+ UnixTime Timestamp
+}
+
// CreateTimelineItem replace a Create operation in the Timeline and hold its edition history
type CreateTimelineItem struct {
- hash git.Hash
- History []Comment
+ CommentTimelineItem
}
func NewCreateTimelineItem(hash git.Hash, comment Comment) *CreateTimelineItem {
return &CreateTimelineItem{
- hash: hash,
- History: []Comment{
- comment,
+ CommentTimelineItem: CommentTimelineItem{
+ hash: hash,
+ Author: comment.Author,
+ Message: comment.Message,
+ Files: comment.Files,
+ CreatedAt: comment.UnixTime,
+ LastEdit: comment.UnixTime,
+ History: []CommentHistoryStep{
+ {
+ Message: comment.Message,
+ UnixTime: comment.UnixTime,
+ },
+ },
},
}
}
-func (c *CreateTimelineItem) Hash() (git.Hash, error) {
- return c.hash, nil
-}
-
-func (c *CreateTimelineItem) LastState() Comment {
- if len(c.History) == 0 {
- panic("no history yet")
- }
-
- return c.History[len(c.History)-1]
-}
-
// CommentTimelineItem replace a Comment in the Timeline and hold its edition history
type CommentTimelineItem struct {
- hash git.Hash
- History []Comment
+ hash git.Hash
+ Author Person
+ Message string
+ Files []git.Hash
+ CreatedAt Timestamp
+ LastEdit Timestamp
+ History []CommentHistoryStep
}
func NewCommentTimelineItem(hash git.Hash, comment Comment) *CommentTimelineItem {
return &CommentTimelineItem{
- hash: hash,
- History: []Comment{
- comment,
+ hash: hash,
+ Author: comment.Author,
+ Message: comment.Message,
+ Files: comment.Files,
+ CreatedAt: comment.UnixTime,
+ LastEdit: comment.UnixTime,
+ History: []CommentHistoryStep{
+ {
+ Message: comment.Message,
+ UnixTime: comment.UnixTime,
+ },
},
}
}
@@ -53,10 +70,18 @@ func (c *CommentTimelineItem) Hash() (git.Hash, error) {
return c.hash, nil
}
-func (c *CommentTimelineItem) LastState() Comment {
- if len(c.History) == 0 {
- panic("no history yet")
- }
+// Append will append a new comment in the history and update the other values
+func (c *CommentTimelineItem) Append(comment Comment) {
+ c.Message = comment.Message
+ c.Files = comment.Files
+ c.LastEdit = comment.UnixTime
+ c.History = append(c.History, CommentHistoryStep{
+ Message: comment.Message,
+ UnixTime: comment.UnixTime,
+ })
+}
- return c.History[len(c.History)-1]
+// Edited say if the comment was edited
+func (c *CommentTimelineItem) Edited() bool {
+ return len(c.History) > 1
}
diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml
index 4ff24f4e..9c0e0842 100644
--- a/graphql/gqlgen.yml
+++ b/graphql/gqlgen.yml
@@ -33,6 +33,8 @@ models:
model: github.com/MichaelMure/git-bug/bug.LabelChangeOperation
TimelineItem:
model: github.com/MichaelMure/git-bug/bug.TimelineItem
+ CommentHistoryStep:
+ model: github.com/MichaelMure/git-bug/bug.CommentHistoryStep
CreateTimelineItem:
model: github.com/MichaelMure/git-bug/bug.CreateTimelineItem
CommentTimelineItem:
diff --git a/graphql/graph/gen_graph.go b/graphql/graph/gen_graph.go
index 032cf5cb..01e3bb91 100644
--- a/graphql/graph/gen_graph.go
+++ b/graphql/graph/gen_graph.go
@@ -37,7 +37,10 @@ type Config struct {
type ResolverRoot interface {
AddCommentOperation() AddCommentOperationResolver
Bug() BugResolver
+ CommentHistoryStep() CommentHistoryStepResolver
+ CommentTimelineItem() CommentTimelineItemResolver
CreateOperation() CreateOperationResolver
+ CreateTimelineItem() CreateTimelineItemResolver
LabelChangeOperation() LabelChangeOperationResolver
Mutation() MutationResolver
Query() QueryResolver
@@ -101,9 +104,19 @@ type ComplexityRoot struct {
Node func(childComplexity int) int
}
+ CommentHistoryStep struct {
+ Message func(childComplexity int) int
+ Date func(childComplexity int) int
+ }
+
CommentTimelineItem struct {
Hash func(childComplexity int) int
- LastState func(childComplexity int) int
+ Author func(childComplexity int) int
+ Message func(childComplexity int) int
+ Files func(childComplexity int) int
+ CreatedAt func(childComplexity int) int
+ LastEdit func(childComplexity int) int
+ Edited func(childComplexity int) int
History func(childComplexity int) int
}
@@ -117,7 +130,12 @@ type ComplexityRoot struct {
CreateTimelineItem struct {
Hash func(childComplexity int) int
- LastState func(childComplexity int) int
+ Author func(childComplexity int) int
+ Message func(childComplexity int) int
+ Files func(childComplexity int) int
+ CreatedAt func(childComplexity int) int
+ LastEdit func(childComplexity int) int
+ Edited func(childComplexity int) int
History func(childComplexity int) int
}
@@ -214,10 +232,21 @@ type BugResolver interface {
Timeline(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.TimelineItemConnection, error)
Operations(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.OperationConnection, error)
}
+type CommentHistoryStepResolver interface {
+ Date(ctx context.Context, obj *bug.CommentHistoryStep) (time.Time, error)
+}
+type CommentTimelineItemResolver interface {
+ CreatedAt(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error)
+ LastEdit(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error)
+}
type CreateOperationResolver interface {
Author(ctx context.Context, obj *bug.CreateOperation) (bug.Person, error)
Date(ctx context.Context, obj *bug.CreateOperation) (time.Time, error)
}
+type CreateTimelineItemResolver interface {
+ CreatedAt(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error)
+ LastEdit(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error)
+}
type LabelChangeOperationResolver interface {
Author(ctx context.Context, obj *bug.LabelChangeOperation) (bug.Person, error)
Date(ctx context.Context, obj *bug.LabelChangeOperation) (time.Time, error)
@@ -1134,6 +1163,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.CommentEdge.Node(childComplexity), true
+ case "CommentHistoryStep.message":
+ if e.complexity.CommentHistoryStep.Message == nil {
+ break
+ }
+
+ return e.complexity.CommentHistoryStep.Message(childComplexity), true
+
+ case "CommentHistoryStep.date":
+ if e.complexity.CommentHistoryStep.Date == nil {
+ break
+ }
+
+ return e.complexity.CommentHistoryStep.Date(childComplexity), true
+
case "CommentTimelineItem.hash":
if e.complexity.CommentTimelineItem.Hash == nil {
break
@@ -1141,12 +1184,47 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.CommentTimelineItem.Hash(childComplexity), true
- case "CommentTimelineItem.lastState":
- if e.complexity.CommentTimelineItem.LastState == nil {
+ case "CommentTimelineItem.author":
+ if e.complexity.CommentTimelineItem.Author == nil {
+ break
+ }
+
+ return e.complexity.CommentTimelineItem.Author(childComplexity), true
+
+ case "CommentTimelineItem.message":
+ if e.complexity.CommentTimelineItem.Message == nil {
+ break
+ }
+
+ return e.complexity.CommentTimelineItem.Message(childComplexity), true
+
+ case "CommentTimelineItem.files":
+ if e.complexity.CommentTimelineItem.Files == nil {
break
}
- return e.complexity.CommentTimelineItem.LastState(childComplexity), true
+ return e.complexity.CommentTimelineItem.Files(childComplexity), true
+
+ case "CommentTimelineItem.createdAt":
+ if e.complexity.CommentTimelineItem.CreatedAt == nil {
+ break
+ }
+
+ return e.complexity.CommentTimelineItem.CreatedAt(childComplexity), true
+
+ case "CommentTimelineItem.lastEdit":
+ if e.complexity.CommentTimelineItem.LastEdit == nil {
+ break
+ }
+
+ return e.complexity.CommentTimelineItem.LastEdit(childComplexity), true
+
+ case "CommentTimelineItem.edited":
+ if e.complexity.CommentTimelineItem.Edited == nil {
+ break
+ }
+
+ return e.complexity.CommentTimelineItem.Edited(childComplexity), true
case "CommentTimelineItem.history":
if e.complexity.CommentTimelineItem.History == nil {
@@ -1197,12 +1275,47 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.CreateTimelineItem.Hash(childComplexity), true
- case "CreateTimelineItem.lastState":
- if e.complexity.CreateTimelineItem.LastState == nil {
+ case "CreateTimelineItem.author":
+ if e.complexity.CreateTimelineItem.Author == nil {
+ break
+ }
+
+ return e.complexity.CreateTimelineItem.Author(childComplexity), true
+
+ case "CreateTimelineItem.message":
+ if e.complexity.CreateTimelineItem.Message == nil {
+ break
+ }
+
+ return e.complexity.CreateTimelineItem.Message(childComplexity), true
+
+ case "CreateTimelineItem.files":
+ if e.complexity.CreateTimelineItem.Files == nil {
+ break
+ }
+
+ return e.complexity.CreateTimelineItem.Files(childComplexity), true
+
+ case "CreateTimelineItem.createdAt":
+ if e.complexity.CreateTimelineItem.CreatedAt == nil {
+ break
+ }
+
+ return e.complexity.CreateTimelineItem.CreatedAt(childComplexity), true
+
+ case "CreateTimelineItem.lastEdit":
+ if e.complexity.CreateTimelineItem.LastEdit == nil {
+ break
+ }
+
+ return e.complexity.CreateTimelineItem.LastEdit(childComplexity), true
+
+ case "CreateTimelineItem.edited":
+ if e.complexity.CreateTimelineItem.Edited == nil {
break
}
- return e.complexity.CreateTimelineItem.LastState(childComplexity), true
+ return e.complexity.CreateTimelineItem.Edited(childComplexity), true
case "CreateTimelineItem.history":
if e.complexity.CreateTimelineItem.History == nil {
@@ -2816,12 +2929,97 @@ func (ec *executionContext) _CommentEdge_node(ctx context.Context, field graphql
return ec._Comment(ctx, field.Selections, &res)
}
+var commentHistoryStepImplementors = []string{"CommentHistoryStep"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _CommentHistoryStep(ctx context.Context, sel ast.SelectionSet, obj *bug.CommentHistoryStep) graphql.Marshaler {
+ fields := graphql.CollectFields(ctx, sel, commentHistoryStepImplementors)
+
+ var wg sync.WaitGroup
+ out := graphql.NewOrderedMap(len(fields))
+ invalid := false
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("CommentHistoryStep")
+ case "message":
+ out.Values[i] = ec._CommentHistoryStep_message(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "date":
+ wg.Add(1)
+ go func(i int, field graphql.CollectedField) {
+ out.Values[i] = ec._CommentHistoryStep_date(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ wg.Done()
+ }(i, field)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+ wg.Wait()
+ if invalid {
+ return graphql.Null
+ }
+ return out
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentHistoryStep_message(ctx context.Context, field graphql.CollectedField, obj *bug.CommentHistoryStep) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentHistoryStep",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Message, nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(string)
+ rctx.Result = res
+ return graphql.MarshalString(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentHistoryStep_date(ctx context.Context, field graphql.CollectedField, obj *bug.CommentHistoryStep) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentHistoryStep",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CommentHistoryStep().Date(ctx, obj)
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ rctx.Result = res
+ return graphql.MarshalTime(res)
+}
+
var commentTimelineItemImplementors = []string{"CommentTimelineItem", "TimelineItem"}
// nolint: gocyclo, errcheck, gas, goconst
func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.SelectionSet, obj *bug.CommentTimelineItem) graphql.Marshaler {
fields := graphql.CollectFields(ctx, sel, commentTimelineItemImplementors)
+ var wg sync.WaitGroup
out := graphql.NewOrderedMap(len(fields))
invalid := false
for i, field := range fields {
@@ -2835,8 +3033,41 @@ func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.Se
if out.Values[i] == graphql.Null {
invalid = true
}
- case "lastState":
- out.Values[i] = ec._CommentTimelineItem_lastState(ctx, field, obj)
+ case "author":
+ out.Values[i] = ec._CommentTimelineItem_author(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "message":
+ out.Values[i] = ec._CommentTimelineItem_message(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "files":
+ out.Values[i] = ec._CommentTimelineItem_files(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "createdAt":
+ wg.Add(1)
+ go func(i int, field graphql.CollectedField) {
+ out.Values[i] = ec._CommentTimelineItem_createdAt(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ wg.Done()
+ }(i, field)
+ case "lastEdit":
+ wg.Add(1)
+ go func(i int, field graphql.CollectedField) {
+ out.Values[i] = ec._CommentTimelineItem_lastEdit(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ wg.Done()
+ }(i, field)
+ case "edited":
+ out.Values[i] = ec._CommentTimelineItem_edited(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalid = true
}
@@ -2849,7 +3080,7 @@ func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.Se
panic("unknown field " + strconv.Quote(field.Name))
}
}
-
+ wg.Wait()
if invalid {
return graphql.Null
}
@@ -2879,7 +3110,7 @@ func (ec *executionContext) _CommentTimelineItem_hash(ctx context.Context, field
}
// nolint: vetshadow
-func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+func (ec *executionContext) _CommentTimelineItem_author(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
rctx := &graphql.ResolverContext{
Object: "CommentTimelineItem",
Args: nil,
@@ -2887,7 +3118,7 @@ func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context,
}
ctx = graphql.WithResolverContext(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
- return obj.LastState(), nil
+ return obj.Author, nil
})
if resTmp == nil {
if !ec.HasError(rctx) {
@@ -2895,10 +3126,129 @@ func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context,
}
return graphql.Null
}
- res := resTmp.(bug.Comment)
+ res := resTmp.(bug.Person)
rctx.Result = res
- return ec._Comment(ctx, field.Selections, &res)
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentTimelineItem_message(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Message, nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(string)
+ rctx.Result = res
+ return graphql.MarshalString(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentTimelineItem_files(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Files, nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.([]git.Hash)
+ rctx.Result = res
+
+ arr1 := make(graphql.Array, len(res))
+
+ for idx1 := range res {
+ arr1[idx1] = func() graphql.Marshaler {
+ return res[idx1]
+ }()
+ }
+
+ return arr1
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentTimelineItem_createdAt(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CommentTimelineItem().CreatedAt(ctx, obj)
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ rctx.Result = res
+ return graphql.MarshalTime(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentTimelineItem_lastEdit(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CommentTimelineItem().LastEdit(ctx, obj)
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ rctx.Result = res
+ return graphql.MarshalTime(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CommentTimelineItem_edited(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CommentTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Edited(), nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(bool)
+ rctx.Result = res
+ return graphql.MarshalBoolean(res)
}
// nolint: vetshadow
@@ -2918,7 +3268,7 @@ func (ec *executionContext) _CommentTimelineItem_history(ctx context.Context, fi
}
return graphql.Null
}
- res := resTmp.([]bug.Comment)
+ res := resTmp.([]bug.CommentHistoryStep)
rctx.Result = res
arr1 := make(graphql.Array, len(res))
@@ -2942,7 +3292,7 @@ func (ec *executionContext) _CommentTimelineItem_history(ctx context.Context, fi
}
arr1[idx1] = func() graphql.Marshaler {
- return ec._Comment(ctx, field.Selections, &res[idx1])
+ return ec._CommentHistoryStep(ctx, field.Selections, &res[idx1])
}()
}
if isLen1 {
@@ -3141,6 +3491,7 @@ var createTimelineItemImplementors = []string{"CreateTimelineItem", "TimelineIte
func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.SelectionSet, obj *bug.CreateTimelineItem) graphql.Marshaler {
fields := graphql.CollectFields(ctx, sel, createTimelineItemImplementors)
+ var wg sync.WaitGroup
out := graphql.NewOrderedMap(len(fields))
invalid := false
for i, field := range fields {
@@ -3154,8 +3505,41 @@ func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.Sel
if out.Values[i] == graphql.Null {
invalid = true
}
- case "lastState":
- out.Values[i] = ec._CreateTimelineItem_lastState(ctx, field, obj)
+ case "author":
+ out.Values[i] = ec._CreateTimelineItem_author(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "message":
+ out.Values[i] = ec._CreateTimelineItem_message(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "files":
+ out.Values[i] = ec._CreateTimelineItem_files(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ case "createdAt":
+ wg.Add(1)
+ go func(i int, field graphql.CollectedField) {
+ out.Values[i] = ec._CreateTimelineItem_createdAt(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ wg.Done()
+ }(i, field)
+ case "lastEdit":
+ wg.Add(1)
+ go func(i int, field graphql.CollectedField) {
+ out.Values[i] = ec._CreateTimelineItem_lastEdit(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ wg.Done()
+ }(i, field)
+ case "edited":
+ out.Values[i] = ec._CreateTimelineItem_edited(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalid = true
}
@@ -3168,7 +3552,7 @@ func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.Sel
panic("unknown field " + strconv.Quote(field.Name))
}
}
-
+ wg.Wait()
if invalid {
return graphql.Null
}
@@ -3198,7 +3582,7 @@ func (ec *executionContext) _CreateTimelineItem_hash(ctx context.Context, field
}
// nolint: vetshadow
-func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+func (ec *executionContext) _CreateTimelineItem_author(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
rctx := &graphql.ResolverContext{
Object: "CreateTimelineItem",
Args: nil,
@@ -3206,7 +3590,7 @@ func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, f
}
ctx = graphql.WithResolverContext(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
- return obj.LastState(), nil
+ return obj.Author, nil
})
if resTmp == nil {
if !ec.HasError(rctx) {
@@ -3214,10 +3598,129 @@ func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, f
}
return graphql.Null
}
- res := resTmp.(bug.Comment)
+ res := resTmp.(bug.Person)
rctx.Result = res
- return ec._Comment(ctx, field.Selections, &res)
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CreateTimelineItem_message(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CreateTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Message, nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(string)
+ rctx.Result = res
+ return graphql.MarshalString(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CreateTimelineItem_files(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CreateTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Files, nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.([]git.Hash)
+ rctx.Result = res
+
+ arr1 := make(graphql.Array, len(res))
+
+ for idx1 := range res {
+ arr1[idx1] = func() graphql.Marshaler {
+ return res[idx1]
+ }()
+ }
+
+ return arr1
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CreateTimelineItem_createdAt(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CreateTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CreateTimelineItem().CreatedAt(ctx, obj)
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ rctx.Result = res
+ return graphql.MarshalTime(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CreateTimelineItem_lastEdit(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CreateTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CreateTimelineItem().LastEdit(ctx, obj)
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ rctx.Result = res
+ return graphql.MarshalTime(res)
+}
+
+// nolint: vetshadow
+func (ec *executionContext) _CreateTimelineItem_edited(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler {
+ rctx := &graphql.ResolverContext{
+ Object: "CreateTimelineItem",
+ Args: nil,
+ Field: field,
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) {
+ return obj.Edited(), nil
+ })
+ if resTmp == nil {
+ if !ec.HasError(rctx) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(bool)
+ rctx.Result = res
+ return graphql.MarshalBoolean(res)
}
// nolint: vetshadow
@@ -3237,7 +3740,7 @@ func (ec *executionContext) _CreateTimelineItem_history(ctx context.Context, fie
}
return graphql.Null
}
- res := resTmp.([]bug.Comment)
+ res := resTmp.([]bug.CommentHistoryStep)
rctx.Result = res
arr1 := make(graphql.Array, len(res))
@@ -3261,7 +3764,7 @@ func (ec *executionContext) _CreateTimelineItem_history(ctx context.Context, fie
}
arr1[idx1] = func() graphql.Marshaler {
- return ec._Comment(ctx, field.Selections, &res[idx1])
+ return ec._CommentHistoryStep(ctx, field.Selections, &res[idx1])
}()
}
if isLen1 {
@@ -6603,16 +7106,31 @@ type TimelineItemEdge {
node: TimelineItem!
}
+type CommentHistoryStep {
+ message: String!
+ date: Time!
+}
+
type CreateTimelineItem implements TimelineItem {
hash: Hash!
- lastState: Comment!
- history: [Comment!]!
+ author: Person!
+ message: String!
+ files: [Hash!]!
+ createdAt: Time!
+ lastEdit: Time!
+ edited: Boolean!
+ history: [CommentHistoryStep!]!
}
type CommentTimelineItem implements TimelineItem {
hash: Hash!
- lastState: Comment!
- history: [Comment!]!
+ author: Person!
+ message: String!
+ files: [Hash!]!
+ createdAt: Time!
+ lastEdit: Time!
+ edited: Boolean!
+ history: [CommentHistoryStep!]!
}
"""The connection type for Bug."""
diff --git a/graphql/resolvers/root.go b/graphql/resolvers/root.go
index ff181784..2322edc7 100644
--- a/graphql/resolvers/root.go
+++ b/graphql/resolvers/root.go
@@ -32,10 +32,22 @@ func (RootResolver) AddCommentOperation() graph.AddCommentOperationResolver {
return &addCommentOperationResolver{}
}
-func (r RootResolver) Bug() graph.BugResolver {
+func (RootResolver) Bug() graph.BugResolver {
return &bugResolver{}
}
+func (RootResolver) CommentHistoryStep() graph.CommentHistoryStepResolver {
+ return &commentHistoryStepResolver{}
+}
+
+func (RootResolver) CommentTimelineItem() graph.CommentTimelineItemResolver {
+ return &commentTimelineItemResolver{}
+}
+
+func (RootResolver) CreateTimelineItem() graph.CreateTimelineItemResolver {
+ return &createTimelineItemResolver{}
+}
+
func (RootResolver) CreateOperation() graph.CreateOperationResolver {
return &createOperationResolver{}
}
@@ -44,7 +56,7 @@ func (RootResolver) LabelChangeOperation() graph.LabelChangeOperationResolver {
return &labelChangeOperation{}
}
-func (r RootResolver) Repository() graph.RepositoryResolver {
+func (RootResolver) Repository() graph.RepositoryResolver {
return &repoResolver{}
}
diff --git a/graphql/resolvers/timeline.go b/graphql/resolvers/timeline.go
new file mode 100644
index 00000000..9b8262fe
--- /dev/null
+++ b/graphql/resolvers/timeline.go
@@ -0,0 +1,36 @@
+package resolvers
+
+import (
+ "context"
+ "time"
+
+ "github.com/MichaelMure/git-bug/bug"
+)
+
+type commentHistoryStepResolver struct{}
+
+func (commentHistoryStepResolver) Date(ctx context.Context, obj *bug.CommentHistoryStep) (time.Time, error) {
+ return obj.UnixTime.Time(), nil
+}
+
+type commentTimelineItemResolver struct{}
+
+func (commentTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) {
+ return obj.CreatedAt.Time(), nil
+}
+
+func (commentTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) {
+ return obj.LastEdit.Time(), nil
+}
+
+type createTimelineItemResolver struct{}
+
+func (createTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) {
+ return obj.CreatedAt.Time(), nil
+
+}
+
+func (createTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) {
+ return obj.LastEdit.Time(), nil
+
+}
diff --git a/graphql/schema.graphql b/graphql/schema.graphql
index 2e685779..5c0d759f 100644
--- a/graphql/schema.graphql
+++ b/graphql/schema.graphql
@@ -141,16 +141,31 @@ type TimelineItemEdge {
node: TimelineItem!
}
+type CommentHistoryStep {
+ message: String!
+ date: Time!
+}
+
type CreateTimelineItem implements TimelineItem {
hash: Hash!
- lastState: Comment!
- history: [Comment!]!
+ author: Person!
+ message: String!
+ files: [Hash!]!
+ createdAt: Time!
+ lastEdit: Time!
+ edited: Boolean!
+ history: [CommentHistoryStep!]!
}
type CommentTimelineItem implements TimelineItem {
hash: Hash!
- lastState: Comment!
- history: [Comment!]!
+ author: Person!
+ message: String!
+ files: [Hash!]!
+ createdAt: Time!
+ lastEdit: Time!
+ edited: Boolean!
+ history: [CommentHistoryStep!]!
}
"""The connection type for Bug."""