+141
-2
@@ -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
|
||||
|
||||
@@ -113,6 +113,16 @@ type Mutation {
|
||||
removeFile(id: String!): File
|
||||
|
||||
|
||||
# Add a chapter to a story
|
||||
addChapter(input: ChapterAddInput!): Chapter!
|
||||
|
||||
# Edit a chapter
|
||||
editChapter(input: ChapterEditInput!): Chapter!
|
||||
|
||||
# Remove a chapter
|
||||
removeChapter(id: String!): Chapter!
|
||||
|
||||
|
||||
# Log in
|
||||
login(username: String!, password: String!): Session!
|
||||
|
||||
|
||||
@@ -21,3 +21,39 @@ type Chapter {
|
||||
# The date of edit.
|
||||
editedDate: String!
|
||||
}
|
||||
|
||||
# Input for addChapter mutation
|
||||
input ChapterAddInput {
|
||||
# The story to add a chapter to
|
||||
storyId: String!
|
||||
|
||||
# The title to give the chapter. It can not be left empty
|
||||
title: String!
|
||||
|
||||
# The author to set for the chapter. It will use the logged in user ID, and only
|
||||
# users with appropriate permissions can post as another author. Even then, it's only
|
||||
# for importing/moving content. This author name will not be used when logging the
|
||||
# submission
|
||||
author: String
|
||||
|
||||
# The markdown source for the content
|
||||
source: String!
|
||||
|
||||
# Optionally, assign a fictional date for the chapter
|
||||
fictionalDate: String
|
||||
}
|
||||
|
||||
# Input for editChapter mutation
|
||||
input ChapterEditInput {
|
||||
# The chapter to edit
|
||||
id: String!
|
||||
|
||||
# Change the chapter's title
|
||||
title: String
|
||||
|
||||
# Change the source
|
||||
source: String
|
||||
|
||||
# Set the fictional date for a chapter
|
||||
fictionalDate: String
|
||||
}
|
||||
Reference in New Issue
Block a user