|
|
@ -4,18 +4,20 @@ import ( |
|
|
|
"context" |
|
|
|
"time" |
|
|
|
|
|
|
|
"git.aiterp.net/rpdata/api/internal/session" |
|
|
|
"git.aiterp.net/rpdata/api/model/change" |
|
|
|
"git.aiterp.net/rpdata/api/model/story" |
|
|
|
) |
|
|
|
|
|
|
|
// ChapterResolver for the Chapter graphql type
|
|
|
|
type ChapterResolver struct{ C story.Chapter } |
|
|
|
|
|
|
|
// ChapterArgs is args for channel query
|
|
|
|
// ChapterArgs is args for chapter query
|
|
|
|
type ChapterArgs struct { |
|
|
|
ID string |
|
|
|
} |
|
|
|
|
|
|
|
// Chapter implements the channel query
|
|
|
|
// Chapter implements the chapter query
|
|
|
|
func (r *QueryResolver) Chapter(ctx context.Context, args *ChapterArgs) (*ChapterResolver, error) { |
|
|
|
chapter, err := story.FindChapterID(args.ID) |
|
|
|
if err != nil { |
|
|
@ -25,6 +27,143 @@ func (r *QueryResolver) Chapter(ctx context.Context, args *ChapterArgs) (*Chapte |
|
|
|
return &ChapterResolver{C: chapter}, nil |
|
|
|
} |
|
|
|
|
|
|
|
// AddChapterArgs is args for the addChapter mutation
|
|
|
|
type AddChapterArgs struct { |
|
|
|
Input *AddChapterInput |
|
|
|
} |
|
|
|
|
|
|
|
// AddChapterInput is input for the addChapter mutation
|
|
|
|
type AddChapterInput struct { |
|
|
|
StoryID string |
|
|
|
Title string |
|
|
|
Author *string |
|
|
|
Source string |
|
|
|
FictionalDate *string |
|
|
|
} |
|
|
|
|
|
|
|
// AddChapter implements the addChapter mutation
|
|
|
|
func (r *MutationResolver) AddChapter(ctx context.Context, args *AddChapterArgs) (*ChapterResolver, error) { |
|
|
|
user := session.FromContext(ctx).User() |
|
|
|
if user == nil || !user.Permitted("member", "chapter.add") { |
|
|
|
return nil, ErrUnauthorized |
|
|
|
} |
|
|
|
|
|
|
|
story, err := story.FindID(args.Input.StoryID) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
author := user.ID |
|
|
|
if args.Input.Author != nil { |
|
|
|
author = *args.Input.Author |
|
|
|
|
|
|
|
if user.ID != author && !user.Permitted("chapter.add") { |
|
|
|
return nil, ErrPermissionDenied |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fictionalDate := time.Time{} |
|
|
|
if args.Input.FictionalDate != nil { |
|
|
|
fictionalDate, err = time.Parse(time.RFC3339Nano, *args.Input.FictionalDate) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
chapter, err := story.AddChapter(args.Input.Title, author, args.Input.Source, time.Now(), fictionalDate) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
change.Submit("Chapter", "add", user.ID, chapter.ID, map[string]interface{}{ |
|
|
|
"title": args.Input.Title, |
|
|
|
"author": author, |
|
|
|
"fictionalDate": fictionalDate, |
|
|
|
}) |
|
|
|
|
|
|
|
return &ChapterResolver{C: chapter}, nil |
|
|
|
} |
|
|
|
|
|
|
|
// EditChapterArgs is args for the addChapter mutation
|
|
|
|
type EditChapterArgs struct { |
|
|
|
Input *EditChapterInput |
|
|
|
} |
|
|
|
|
|
|
|
// EditChapterInput is input for the addChapter mutation
|
|
|
|
type EditChapterInput struct { |
|
|
|
ID string |
|
|
|
Title *string |
|
|
|
Source *string |
|
|
|
FictionalDate *string |
|
|
|
} |
|
|
|
|
|
|
|
// EditChapter implements the editChapter mutation
|
|
|
|
func (r *MutationResolver) EditChapter(ctx context.Context, args *EditChapterArgs) (*ChapterResolver, error) { |
|
|
|
user := session.FromContext(ctx).User() |
|
|
|
if user == nil || !user.Permitted("member", "chapter.edit") { |
|
|
|
return nil, ErrUnauthorized |
|
|
|
} |
|
|
|
|
|
|
|
chapter, err := story.FindChapterID(args.Input.ID) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
if chapter.Author != user.ID && !user.Permitted("chapter.edit") { |
|
|
|
return nil, ErrPermissionDenied |
|
|
|
} |
|
|
|
|
|
|
|
var fictionalDate *time.Time |
|
|
|
if args.Input.FictionalDate != nil { |
|
|
|
date, err := time.Parse(time.RFC3339Nano, *args.Input.FictionalDate) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
fictionalDate = &date |
|
|
|
} |
|
|
|
|
|
|
|
err = chapter.Edit(args.Input.Title, args.Input.Source, fictionalDate) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
change.Submit("Chapter", "edit", user.ID, chapter.ID, map[string]interface{}{ |
|
|
|
"title": args.Input.Title, |
|
|
|
"source": args.Input.Source, |
|
|
|
"fictionalDate": fictionalDate, |
|
|
|
}) |
|
|
|
|
|
|
|
return &ChapterResolver{C: chapter}, nil |
|
|
|
} |
|
|
|
|
|
|
|
// DeleteChapterArgs is args for the addChapter mutation
|
|
|
|
type DeleteChapterArgs struct { |
|
|
|
ID string |
|
|
|
} |
|
|
|
|
|
|
|
// RemoveChapter implements the removeChapter mutation
|
|
|
|
func (r *MutationResolver) RemoveChapter(ctx context.Context, args *DeleteChapterArgs) (*ChapterResolver, error) { |
|
|
|
user := session.FromContext(ctx).User() |
|
|
|
if user == nil || !user.Permitted("member", "chapter.edit") { |
|
|
|
return nil, ErrUnauthorized |
|
|
|
} |
|
|
|
|
|
|
|
chapter, err := story.FindChapterID(args.ID) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
err = chapter.Remove() |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
change.Submit("Chapter", "remove", user.ID, chapter.ID, nil) |
|
|
|
|
|
|
|
return &ChapterResolver{C: chapter}, nil |
|
|
|
} |
|
|
|
|
|
|
|
// ID resolves Chapter.id
|
|
|
|
func (r *ChapterResolver) ID() string { |
|
|
|
return r.C.ID |
|
|
|