Add resolvers for user albums and root_albums
This commit is contained in:
parent
aeb05bca49
commit
96546f6556
|
@ -24,6 +24,9 @@ models:
|
||||||
model: github.com/99designs/gqlgen/graphql.IntID
|
model: github.com/99designs/gqlgen/graphql.IntID
|
||||||
User:
|
User:
|
||||||
model: github.com/photoview/photoview/api/graphql/models.User
|
model: github.com/photoview/photoview/api/graphql/models.User
|
||||||
|
fields:
|
||||||
|
albums:
|
||||||
|
resolver: true
|
||||||
Media:
|
Media:
|
||||||
model: github.com/photoview/photoview/api/graphql/models.Media
|
model: github.com/photoview/photoview/api/graphql/models.Media
|
||||||
MediaURL:
|
MediaURL:
|
||||||
|
|
|
@ -44,6 +44,7 @@ type ResolverRoot interface {
|
||||||
Query() QueryResolver
|
Query() QueryResolver
|
||||||
ShareToken() ShareTokenResolver
|
ShareToken() ShareTokenResolver
|
||||||
Subscription() SubscriptionResolver
|
Subscription() SubscriptionResolver
|
||||||
|
User() UserResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
type DirectiveRoot struct {
|
type DirectiveRoot struct {
|
||||||
|
@ -191,10 +192,11 @@ type ComplexityRoot struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
User struct {
|
User struct {
|
||||||
Admin func(childComplexity int) int
|
Admin func(childComplexity int) int
|
||||||
Albums func(childComplexity int) int
|
Albums func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
Username func(childComplexity int) int
|
RootAlbums func(childComplexity int) int
|
||||||
|
Username func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoMetadata struct {
|
VideoMetadata struct {
|
||||||
|
@ -268,6 +270,10 @@ type ShareTokenResolver interface {
|
||||||
type SubscriptionResolver interface {
|
type SubscriptionResolver interface {
|
||||||
Notification(ctx context.Context) (<-chan *models.Notification, error)
|
Notification(ctx context.Context) (<-chan *models.Notification, error)
|
||||||
}
|
}
|
||||||
|
type UserResolver interface {
|
||||||
|
Albums(ctx context.Context, obj *models.User) ([]*models.Album, error)
|
||||||
|
RootAlbums(ctx context.Context, obj *models.User) ([]*models.Album, error)
|
||||||
|
}
|
||||||
|
|
||||||
type executableSchema struct {
|
type executableSchema struct {
|
||||||
resolvers ResolverRoot
|
resolvers ResolverRoot
|
||||||
|
@ -1104,6 +1110,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.User.ID(childComplexity), true
|
return e.complexity.User.ID(childComplexity), true
|
||||||
|
|
||||||
|
case "User.rootAlbums":
|
||||||
|
if e.complexity.User.RootAlbums == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.User.RootAlbums(childComplexity), true
|
||||||
|
|
||||||
case "User.username":
|
case "User.username":
|
||||||
if e.complexity.User.Username == nil {
|
if e.complexity.User.Username == nil {
|
||||||
break
|
break
|
||||||
|
@ -1436,8 +1449,10 @@ type User {
|
||||||
username: String!
|
username: String!
|
||||||
#albums: [Album]
|
#albums: [Album]
|
||||||
# rootPath: String! @isAdmin
|
# rootPath: String! @isAdmin
|
||||||
"Top level albums owned by this user"
|
"All albums owned by this user"
|
||||||
albums: [Album!]! @isAdmin
|
albums: [Album!]! @isAdmin
|
||||||
|
"Top level albums owned by this user"
|
||||||
|
rootAlbums: [Album!]! @isAdmin
|
||||||
admin: Boolean!
|
admin: Boolean!
|
||||||
#shareTokens: [ShareToken]
|
#shareTokens: [ShareToken]
|
||||||
}
|
}
|
||||||
|
@ -5931,15 +5946,15 @@ func (ec *executionContext) _User_albums(ctx context.Context, field graphql.Coll
|
||||||
Object: "User",
|
Object: "User",
|
||||||
Field: field,
|
Field: field,
|
||||||
Args: nil,
|
Args: nil,
|
||||||
IsMethod: false,
|
IsMethod: true,
|
||||||
IsResolver: false,
|
IsResolver: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
directive0 := func(rctx context.Context) (interface{}, error) {
|
directive0 := func(rctx context.Context) (interface{}, error) {
|
||||||
ctx = rctx // use context from middleware stack in children
|
ctx = rctx // use context from middleware stack in children
|
||||||
return obj.Albums, nil
|
return ec.resolvers.User().Albums(rctx, obj)
|
||||||
}
|
}
|
||||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||||
if ec.directives.IsAdmin == nil {
|
if ec.directives.IsAdmin == nil {
|
||||||
|
@ -5955,10 +5970,10 @@ func (ec *executionContext) _User_albums(ctx context.Context, field graphql.Coll
|
||||||
if tmp == nil {
|
if tmp == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if data, ok := tmp.([]models.Album); ok {
|
if data, ok := tmp.([]*models.Album); ok {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be []github.com/photoview/photoview/api/graphql/models.Album`, tmp)
|
return nil, fmt.Errorf(`unexpected type %T from directive, should be []*github.com/photoview/photoview/api/graphql/models.Album`, tmp)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
|
@ -5970,9 +5985,64 @@ func (ec *executionContext) _User_albums(ctx context.Context, field graphql.Coll
|
||||||
}
|
}
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.([]models.Album)
|
res := resTmp.([]*models.Album)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNAlbum2ᚕgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx, field.Selections, res)
|
return ec.marshalNAlbum2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _User_rootAlbums(ctx context.Context, field graphql.CollectedField, obj *models.User) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "User",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
directive0 := func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.User().RootAlbums(rctx, obj)
|
||||||
|
}
|
||||||
|
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||||
|
if ec.directives.IsAdmin == nil {
|
||||||
|
return nil, errors.New("directive isAdmin is not implemented")
|
||||||
|
}
|
||||||
|
return ec.directives.IsAdmin(ctx, obj, directive0)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp, err := directive1(rctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
if tmp == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if data, ok := tmp.([]*models.Album); ok {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf(`unexpected type %T from directive, should be []*github.com/photoview/photoview/api/graphql/models.Album`, tmp)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*models.Album)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNAlbum2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _User_admin(ctx context.Context, field graphql.CollectedField, obj *models.User) (ret graphql.Marshaler) {
|
func (ec *executionContext) _User_admin(ctx context.Context, field graphql.CollectedField, obj *models.User) (ret graphql.Marshaler) {
|
||||||
|
@ -8425,22 +8495,45 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj
|
||||||
case "id":
|
case "id":
|
||||||
out.Values[i] = ec._User_id(ctx, field, obj)
|
out.Values[i] = ec._User_id(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
invalids++
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
case "username":
|
case "username":
|
||||||
out.Values[i] = ec._User_username(ctx, field, obj)
|
out.Values[i] = ec._User_username(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
invalids++
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
case "albums":
|
case "albums":
|
||||||
out.Values[i] = ec._User_albums(ctx, field, obj)
|
field := field
|
||||||
if out.Values[i] == graphql.Null {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
invalids++
|
defer func() {
|
||||||
}
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._User_albums(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
case "rootAlbums":
|
||||||
|
field := field
|
||||||
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._User_rootAlbums(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
case "admin":
|
case "admin":
|
||||||
out.Values[i] = ec._User_admin(ctx, field, obj)
|
out.Values[i] = ec._User_admin(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
invalids++
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
@ -8759,43 +8852,6 @@ func (ec *executionContext) marshalNAlbum2githubᚗcomᚋphotoviewᚋphotoview
|
||||||
return ec._Album(ctx, sel, &v)
|
return ec._Album(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNAlbum2ᚕgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx context.Context, sel ast.SelectionSet, v []models.Album) graphql.Marshaler {
|
|
||||||
ret := make(graphql.Array, len(v))
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
isLen1 := len(v) == 1
|
|
||||||
if !isLen1 {
|
|
||||||
wg.Add(len(v))
|
|
||||||
}
|
|
||||||
for i := range v {
|
|
||||||
i := i
|
|
||||||
fc := &graphql.FieldContext{
|
|
||||||
Index: &i,
|
|
||||||
Result: &v[i],
|
|
||||||
}
|
|
||||||
ctx := graphql.WithFieldContext(ctx, fc)
|
|
||||||
f := func(i int) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
|
||||||
ret = nil
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if !isLen1 {
|
|
||||||
defer wg.Done()
|
|
||||||
}
|
|
||||||
ret[i] = ec.marshalNAlbum2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx, sel, v[i])
|
|
||||||
}
|
|
||||||
if isLen1 {
|
|
||||||
f(i)
|
|
||||||
} else {
|
|
||||||
go f(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNAlbum2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.Album) graphql.Marshaler {
|
func (ec *executionContext) marshalNAlbum2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbumᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.Album) graphql.Marshaler {
|
||||||
ret := make(graphql.Array, len(v))
|
ret := make(graphql.Array, len(v))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
|
@ -3,6 +3,7 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
api "github.com/photoview/photoview/api/graphql"
|
||||||
"github.com/photoview/photoview/api/graphql/auth"
|
"github.com/photoview/photoview/api/graphql/auth"
|
||||||
"github.com/photoview/photoview/api/graphql/models"
|
"github.com/photoview/photoview/api/graphql/models"
|
||||||
"github.com/photoview/photoview/api/scanner"
|
"github.com/photoview/photoview/api/scanner"
|
||||||
|
@ -11,6 +12,14 @@ import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type userResolver struct {
|
||||||
|
*Resolver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) User() api.UserResolver {
|
||||||
|
return &userResolver{r}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *queryResolver) User(ctx context.Context, filter *models.Filter) ([]*models.User, error) {
|
func (r *queryResolver) User(ctx context.Context, filter *models.Filter) ([]*models.User, error) {
|
||||||
|
|
||||||
var users []*models.User
|
var users []*models.User
|
||||||
|
@ -22,6 +31,30 @@ func (r *queryResolver) User(ctx context.Context, filter *models.Filter) ([]*mod
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *userResolver) Albums(ctx context.Context, user *models.User) ([]*models.Album, error) {
|
||||||
|
user.FillAlbums(r.Database)
|
||||||
|
|
||||||
|
pointerAlbums := make([]*models.Album, len(user.Albums))
|
||||||
|
for i, album := range user.Albums {
|
||||||
|
pointerAlbums[i] = &album
|
||||||
|
}
|
||||||
|
|
||||||
|
return pointerAlbums, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *userResolver) RootAlbums(ctx context.Context, user *models.User) (albums []*models.Album, err error) {
|
||||||
|
|
||||||
|
err = r.Database.Model(&user).
|
||||||
|
Where("albums.parent_album_id NOT IN (?)",
|
||||||
|
r.Database.Table("user_albums").
|
||||||
|
Select("albums.id").
|
||||||
|
Joins("JOIN albums ON albums.id = user_albums.album_id AND user_albums.user_id = ?", user.ID),
|
||||||
|
).Or("albums.parent_album_id IS NULL").
|
||||||
|
Association("Albums").Find(&albums)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (r *queryResolver) MyUser(ctx context.Context) (*models.User, error) {
|
func (r *queryResolver) MyUser(ctx context.Context) (*models.User, error) {
|
||||||
|
|
||||||
user := auth.UserFromContext(ctx)
|
user := auth.UserFromContext(ctx)
|
||||||
|
|
|
@ -172,8 +172,10 @@ type User {
|
||||||
username: String!
|
username: String!
|
||||||
#albums: [Album]
|
#albums: [Album]
|
||||||
# rootPath: String! @isAdmin
|
# rootPath: String! @isAdmin
|
||||||
"Top level albums owned by this user"
|
"All albums owned by this user"
|
||||||
albums: [Album!]! @isAdmin
|
albums: [Album!]! @isAdmin
|
||||||
|
"Top level albums owned by this user"
|
||||||
|
rootAlbums: [Album!]! @isAdmin
|
||||||
admin: Boolean!
|
admin: Boolean!
|
||||||
#shareTokens: [ShareToken]
|
#shareTokens: [ShareToken]
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@ const USERS_QUERY = gql`
|
||||||
username
|
username
|
||||||
# rootPath
|
# rootPath
|
||||||
admin
|
admin
|
||||||
|
albums {
|
||||||
|
id
|
||||||
|
filePath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
Loading…
Reference in New Issue