Improve integration with ui
This commit is contained in:
parent
a3a4dda286
commit
6e72caf2f0
|
@ -78,15 +78,21 @@ type ComplexityRoot struct {
|
||||||
|
|
||||||
Photo struct {
|
Photo struct {
|
||||||
Album func(childComplexity int) int
|
Album func(childComplexity int) int
|
||||||
|
Downloads func(childComplexity int) int
|
||||||
Exif func(childComplexity int) int
|
Exif func(childComplexity int) int
|
||||||
HighRes func(childComplexity int) int
|
HighRes func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
Original func(childComplexity int) int
|
|
||||||
Path func(childComplexity int) int
|
Path func(childComplexity int) int
|
||||||
|
Shares func(childComplexity int) int
|
||||||
Thumbnail func(childComplexity int) int
|
Thumbnail func(childComplexity int) int
|
||||||
Title func(childComplexity int) int
|
Title func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhotoDownload struct {
|
||||||
|
Title func(childComplexity int) int
|
||||||
|
URL func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
PhotoExif struct {
|
PhotoExif struct {
|
||||||
Aperture func(childComplexity int) int
|
Aperture func(childComplexity int) int
|
||||||
Camera func(childComplexity int) int
|
Camera func(childComplexity int) int
|
||||||
|
@ -165,11 +171,12 @@ type MutationResolver interface {
|
||||||
SharePhoto(ctx context.Context, photoID int, expire *time.Time, password *string) (*models.ShareToken, error)
|
SharePhoto(ctx context.Context, photoID int, expire *time.Time, password *string) (*models.ShareToken, error)
|
||||||
}
|
}
|
||||||
type PhotoResolver interface {
|
type PhotoResolver interface {
|
||||||
Original(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
|
|
||||||
Thumbnail(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
|
Thumbnail(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
|
||||||
HighRes(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
|
HighRes(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
|
||||||
Album(ctx context.Context, obj *models.Photo) (*models.Album, error)
|
Album(ctx context.Context, obj *models.Photo) (*models.Album, error)
|
||||||
Exif(ctx context.Context, obj *models.Photo) (*models.PhotoExif, error)
|
Exif(ctx context.Context, obj *models.Photo) (*models.PhotoExif, error)
|
||||||
|
Shares(ctx context.Context, obj *models.Photo) ([]*models.ShareToken, error)
|
||||||
|
Downloads(ctx context.Context, obj *models.Photo) ([]*models.PhotoDownload, error)
|
||||||
}
|
}
|
||||||
type QueryResolver interface {
|
type QueryResolver interface {
|
||||||
SiteInfo(ctx context.Context) (*models.SiteInfo, error)
|
SiteInfo(ctx context.Context) (*models.SiteInfo, error)
|
||||||
|
@ -377,6 +384,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Photo.Album(childComplexity), true
|
return e.complexity.Photo.Album(childComplexity), true
|
||||||
|
|
||||||
|
case "Photo.downloads":
|
||||||
|
if e.complexity.Photo.Downloads == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Photo.Downloads(childComplexity), true
|
||||||
|
|
||||||
case "Photo.exif":
|
case "Photo.exif":
|
||||||
if e.complexity.Photo.Exif == nil {
|
if e.complexity.Photo.Exif == nil {
|
||||||
break
|
break
|
||||||
|
@ -398,13 +412,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Photo.ID(childComplexity), true
|
return e.complexity.Photo.ID(childComplexity), true
|
||||||
|
|
||||||
case "Photo.original":
|
|
||||||
if e.complexity.Photo.Original == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.complexity.Photo.Original(childComplexity), true
|
|
||||||
|
|
||||||
case "Photo.path":
|
case "Photo.path":
|
||||||
if e.complexity.Photo.Path == nil {
|
if e.complexity.Photo.Path == nil {
|
||||||
break
|
break
|
||||||
|
@ -412,6 +419,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Photo.Path(childComplexity), true
|
return e.complexity.Photo.Path(childComplexity), true
|
||||||
|
|
||||||
|
case "Photo.shares":
|
||||||
|
if e.complexity.Photo.Shares == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Photo.Shares(childComplexity), true
|
||||||
|
|
||||||
case "Photo.thumbnail":
|
case "Photo.thumbnail":
|
||||||
if e.complexity.Photo.Thumbnail == nil {
|
if e.complexity.Photo.Thumbnail == nil {
|
||||||
break
|
break
|
||||||
|
@ -426,6 +440,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Photo.Title(childComplexity), true
|
return e.complexity.Photo.Title(childComplexity), true
|
||||||
|
|
||||||
|
case "PhotoDownload.title":
|
||||||
|
if e.complexity.PhotoDownload.Title == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.PhotoDownload.Title(childComplexity), true
|
||||||
|
|
||||||
|
case "PhotoDownload.url":
|
||||||
|
if e.complexity.PhotoDownload.URL == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.PhotoDownload.URL(childComplexity), true
|
||||||
|
|
||||||
case "PhotoEXIF.aperture":
|
case "PhotoEXIF.aperture":
|
||||||
if e.complexity.PhotoExif.Aperture == nil {
|
if e.complexity.PhotoExif.Aperture == nil {
|
||||||
break
|
break
|
||||||
|
@ -926,22 +954,26 @@ type PhotoURL {
|
||||||
height: Int!
|
height: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PhotoDownload {
|
||||||
|
title: String!
|
||||||
|
url: String!
|
||||||
|
}
|
||||||
|
|
||||||
type Photo {
|
type Photo {
|
||||||
id: Int!
|
id: Int!
|
||||||
title: String!
|
title: String!
|
||||||
"Local filepath for the photo"
|
"Local filepath for the photo"
|
||||||
path: String!
|
path: String!
|
||||||
"URL to display the photo in full resolution"
|
|
||||||
original: PhotoURL!
|
|
||||||
"URL to display the photo in a smaller resolution"
|
"URL to display the photo in a smaller resolution"
|
||||||
thumbnail: PhotoURL!
|
thumbnail: PhotoURL!
|
||||||
|
"URL to display the photo in full resolution"
|
||||||
highRes: PhotoURL!
|
highRes: PhotoURL!
|
||||||
"The album that holds the photo"
|
"The album that holds the photo"
|
||||||
album: Album!
|
album: Album!
|
||||||
exif: PhotoEXIF
|
exif: PhotoEXIF
|
||||||
|
|
||||||
# shares: [ShareToken]
|
shares: [ShareToken!]!
|
||||||
# downloads: [PhotoDownload]
|
downloads: [PhotoDownload!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
"EXIF metadata from the camera"
|
"EXIF metadata from the camera"
|
||||||
|
@ -2137,43 +2169,6 @@ func (ec *executionContext) _Photo_path(ctx context.Context, field graphql.Colle
|
||||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Photo_original(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
|
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
|
||||||
ret = graphql.Null
|
|
||||||
}
|
|
||||||
ec.Tracer.EndFieldExecution(ctx)
|
|
||||||
}()
|
|
||||||
rctx := &graphql.ResolverContext{
|
|
||||||
Object: "Photo",
|
|
||||||
Field: field,
|
|
||||||
Args: nil,
|
|
||||||
IsMethod: true,
|
|
||||||
}
|
|
||||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
|
||||||
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
|
||||||
ctx = rctx // use context from middleware stack in children
|
|
||||||
return ec.resolvers.Photo().Original(rctx, obj)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
if resTmp == nil {
|
|
||||||
if !ec.HasError(rctx) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
res := resTmp.(*models.PhotoURL)
|
|
||||||
rctx.Result = res
|
|
||||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
|
||||||
return ec.marshalNPhotoURL2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoURL(ctx, field.Selections, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) _Photo_thumbnail(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Photo_thumbnail(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -2319,6 +2314,154 @@ func (ec *executionContext) _Photo_exif(ctx context.Context, field graphql.Colle
|
||||||
return ec.marshalOPhotoEXIF2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoExif(ctx, field.Selections, res)
|
return ec.marshalOPhotoEXIF2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoExif(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Photo_shares(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
ec.Tracer.EndFieldExecution(ctx)
|
||||||
|
}()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "Photo",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Photo().Shares(rctx, obj)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*models.ShareToken)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareTokenᚄ(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Photo_downloads(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
ec.Tracer.EndFieldExecution(ctx)
|
||||||
|
}()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "Photo",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Photo().Downloads(rctx, obj)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*models.PhotoDownload)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNPhotoDownload2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoDownloadᚄ(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _PhotoDownload_title(ctx context.Context, field graphql.CollectedField, obj *models.PhotoDownload) (ret graphql.Marshaler) {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
ec.Tracer.EndFieldExecution(ctx)
|
||||||
|
}()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "PhotoDownload",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Title, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(string)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _PhotoDownload_url(ctx context.Context, field graphql.CollectedField, obj *models.PhotoDownload) (ret graphql.Marshaler) {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
ec.Tracer.EndFieldExecution(ctx)
|
||||||
|
}()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "PhotoDownload",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.URL, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(string)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _PhotoEXIF_photo(ctx context.Context, field graphql.CollectedField, obj *models.PhotoExif) (ret graphql.Marshaler) {
|
func (ec *executionContext) _PhotoEXIF_photo(ctx context.Context, field graphql.CollectedField, obj *models.PhotoExif) (ret graphql.Marshaler) {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -5249,20 +5392,6 @@ func (ec *executionContext) _Photo(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
atomic.AddUint32(&invalids, 1)
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
case "original":
|
|
||||||
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._Photo_original(ctx, field, obj)
|
|
||||||
if res == graphql.Null {
|
|
||||||
atomic.AddUint32(&invalids, 1)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
case "thumbnail":
|
case "thumbnail":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
@ -5316,6 +5445,66 @@ func (ec *executionContext) _Photo(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
res = ec._Photo_exif(ctx, field, obj)
|
res = ec._Photo_exif(ctx, field, obj)
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
case "shares":
|
||||||
|
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._Photo_shares(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
case "downloads":
|
||||||
|
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._Photo_downloads(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch()
|
||||||
|
if invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
var photoDownloadImplementors = []string{"PhotoDownload"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _PhotoDownload(ctx context.Context, sel ast.SelectionSet, obj *models.PhotoDownload) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.RequestContext, sel, photoDownloadImplementors)
|
||||||
|
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
var invalids uint32
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("PhotoDownload")
|
||||||
|
case "title":
|
||||||
|
out.Values[i] = ec._PhotoDownload_title(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
case "url":
|
||||||
|
out.Values[i] = ec._PhotoDownload_url(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
|
@ -6128,6 +6317,57 @@ func (ec *executionContext) marshalNPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphoto
|
||||||
return ec._Photo(ctx, sel, v)
|
return ec._Photo(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNPhotoDownload2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoDownload(ctx context.Context, sel ast.SelectionSet, v models.PhotoDownload) graphql.Marshaler {
|
||||||
|
return ec._PhotoDownload(ctx, sel, &v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNPhotoDownload2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoDownloadᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.PhotoDownload) 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
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Index: &i,
|
||||||
|
Result: &v[i],
|
||||||
|
}
|
||||||
|
ctx := graphql.WithResolverContext(ctx, rctx)
|
||||||
|
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.marshalNPhotoDownload2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoDownload(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
if isLen1 {
|
||||||
|
f(i)
|
||||||
|
} else {
|
||||||
|
go f(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNPhotoDownload2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoDownload(ctx context.Context, sel ast.SelectionSet, v *models.PhotoDownload) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
if !ec.HasError(graphql.GetResolverContext(ctx)) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._PhotoDownload(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNPhotoURL2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoURL(ctx context.Context, sel ast.SelectionSet, v models.PhotoURL) graphql.Marshaler {
|
func (ec *executionContext) marshalNPhotoURL2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhotoURL(ctx context.Context, sel ast.SelectionSet, v models.PhotoURL) graphql.Marshaler {
|
||||||
return ec._PhotoURL(ctx, sel, &v)
|
return ec._PhotoURL(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@ type Filter struct {
|
||||||
Offset *int `json:"offset"`
|
Offset *int `json:"offset"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PhotoDownload struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
// EXIF metadata from the camera
|
// EXIF metadata from the camera
|
||||||
type PhotoExif struct {
|
type PhotoExif struct {
|
||||||
Photo *Photo `json:"photo"`
|
Photo *Photo `json:"photo"`
|
||||||
|
|
|
@ -24,7 +24,6 @@ type PhotoPurpose string
|
||||||
const (
|
const (
|
||||||
PhotoThumbnail PhotoPurpose = "thumbnail"
|
PhotoThumbnail PhotoPurpose = "thumbnail"
|
||||||
PhotoHighRes PhotoPurpose = "high-res"
|
PhotoHighRes PhotoPurpose = "high-res"
|
||||||
PhotoOriginal PhotoPurpose = "original"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PhotoURL struct {
|
type PhotoURL struct {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
api "github.com/viktorstrate/photoview/api/graphql"
|
api "github.com/viktorstrate/photoview/api/graphql"
|
||||||
"github.com/viktorstrate/photoview/api/graphql/auth"
|
"github.com/viktorstrate/photoview/api/graphql/auth"
|
||||||
|
@ -56,12 +57,20 @@ func (r *Resolver) Photo() api.PhotoResolver {
|
||||||
return &photoResolver{r}
|
return &photoResolver{r}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *photoResolver) HighRes(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error) {
|
func (r *photoResolver) Shares(ctx context.Context, obj *models.Photo) ([]*models.ShareToken, error) {
|
||||||
panic("not implemented")
|
log.Println("Photo: shares not implemented")
|
||||||
|
shares := make([]*models.ShareToken, 0)
|
||||||
|
return shares, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *photoResolver) Original(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error) {
|
func (r *photoResolver) Downloads(ctx context.Context, obj *models.Photo) ([]*models.PhotoDownload, error) {
|
||||||
row := r.Database.QueryRow("SELECT * FROM photo_url WHERE photo_id = ? AND purpose = ?", obj.PhotoID, models.PhotoOriginal)
|
log.Println("Photo: downloads not implemented")
|
||||||
|
downloads := make([]*models.PhotoDownload, 0)
|
||||||
|
return downloads, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *photoResolver) HighRes(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error) {
|
||||||
|
row := r.Database.QueryRow("SELECT * FROM photo_url WHERE photo_id = ? AND purpose = ?", obj.PhotoID, models.PhotoHighRes)
|
||||||
|
|
||||||
url, err := models.NewPhotoURLFromRow(row)
|
url, err := models.NewPhotoURLFromRow(row)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -87,5 +96,6 @@ func (r *photoResolver) Album(ctx context.Context, obj *models.Photo) (*models.A
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *photoResolver) Exif(ctx context.Context, obj *models.Photo) (*models.PhotoExif, error) {
|
func (r *photoResolver) Exif(ctx context.Context, obj *models.Photo) (*models.PhotoExif, error) {
|
||||||
panic("not implemented")
|
log.Println("Photo: EXIF not implemented")
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,22 +135,26 @@ type PhotoURL {
|
||||||
height: Int!
|
height: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PhotoDownload {
|
||||||
|
title: String!
|
||||||
|
url: String!
|
||||||
|
}
|
||||||
|
|
||||||
type Photo {
|
type Photo {
|
||||||
id: Int!
|
id: Int!
|
||||||
title: String!
|
title: String!
|
||||||
"Local filepath for the photo"
|
"Local filepath for the photo"
|
||||||
path: String!
|
path: String!
|
||||||
"URL to display the photo in full resolution"
|
|
||||||
original: PhotoURL!
|
|
||||||
"URL to display the photo in a smaller resolution"
|
"URL to display the photo in a smaller resolution"
|
||||||
thumbnail: PhotoURL!
|
thumbnail: PhotoURL!
|
||||||
|
"URL to display the photo in full resolution"
|
||||||
highRes: PhotoURL!
|
highRes: PhotoURL!
|
||||||
"The album that holds the photo"
|
"The album that holds the photo"
|
||||||
album: Album!
|
album: Album!
|
||||||
exif: PhotoEXIF
|
exif: PhotoEXIF
|
||||||
|
|
||||||
# shares: [ShareToken]
|
shares: [ShareToken!]!
|
||||||
# downloads: [PhotoDownload]
|
downloads: [PhotoDownload!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
"EXIF metadata from the camera"
|
"EXIF metadata from the camera"
|
||||||
|
|
|
@ -42,7 +42,7 @@ func PhotoRoutes(db *sql.DB) chi.Router {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if purpose == models.PhotoOriginal {
|
if purpose == models.PhotoHighRes {
|
||||||
var err error
|
var err error
|
||||||
file, err = os.Open(path)
|
file, err = os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -68,15 +68,17 @@ func ProcessImage(tx *sql.Tx, photoPath string, albumId int, content_type string
|
||||||
photoBaseName := photoName[0 : len(photoName)-len(path.Ext(photoName))]
|
photoBaseName := photoName[0 : len(photoName)-len(path.Ext(photoName))]
|
||||||
photoBaseExt := path.Ext(photoName)
|
photoBaseExt := path.Ext(photoName)
|
||||||
|
|
||||||
original_image_name := fmt.Sprintf("%s_%s", photoBaseName, utils.GenerateToken())
|
// high res
|
||||||
original_image_name = strings.ReplaceAll(original_image_name, " ", "_") + photoBaseExt
|
highres_image_name := fmt.Sprintf("%s_%s", photoBaseName, utils.GenerateToken())
|
||||||
|
highres_image_name = strings.ReplaceAll(highres_image_name, " ", "_") + photoBaseExt
|
||||||
|
|
||||||
_, err = tx.Exec("INSERT INTO photo_url (photo_id, photo_name, width, height, purpose, content_type) VALUES (?, ?, ?, ?, ?, ?)", photo_id, original_image_name, image.Bounds().Max.X, image.Bounds().Max.Y, models.PhotoOriginal, content_type)
|
_, err = tx.Exec("INSERT INTO photo_url (photo_id, photo_name, width, height, purpose, content_type) VALUES (?, ?, ?, ?, ?, ?)", photo_id, highres_image_name, image.Bounds().Max.X, image.Bounds().Max.Y, models.PhotoHighRes, content_type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Could not insert original photo url: %d, %s\n", photo_id, photoName)
|
log.Printf("Could not insert high-res photo url: %d, %s\n", photo_id, photoName)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thumbnail
|
||||||
thumbnailImage := resize.Thumbnail(1024, 1024, image, resize.Bilinear)
|
thumbnailImage := resize.Thumbnail(1024, 1024, image, resize.Bilinear)
|
||||||
|
|
||||||
if _, err := os.Stat("image-cache"); os.IsNotExist(err) {
|
if _, err := os.Stat("image-cache"); os.IsNotExist(err) {
|
||||||
|
|
|
@ -177,7 +177,7 @@ func directoryContainsPhotos(rootPath string, cache *scanner_cache) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var supported_mimetypes = [...]string{
|
var SupportedMimetypes = [...]string{
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/tiff",
|
"image/tiff",
|
||||||
|
@ -186,6 +186,13 @@ var supported_mimetypes = [...]string{
|
||||||
"image/bmp",
|
"image/bmp",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var WebMimetypes = [...]string{
|
||||||
|
"image/jpeg",
|
||||||
|
"image/png",
|
||||||
|
"image/webp",
|
||||||
|
"image/bmp",
|
||||||
|
}
|
||||||
|
|
||||||
func isPathImage(path string, cache *scanner_cache) bool {
|
func isPathImage(path string, cache *scanner_cache) bool {
|
||||||
if cache.get_photo_type(path) != nil {
|
if cache.get_photo_type(path) != nil {
|
||||||
log.Printf("Image cache hit: %s\n", path)
|
log.Printf("Image cache hit: %s\n", path)
|
||||||
|
@ -209,7 +216,7 @@ func isPathImage(path string, cache *scanner_cache) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, supported_mime := range supported_mimetypes {
|
for _, supported_mime := range SupportedMimetypes {
|
||||||
if supported_mime == imgType.MIME.Value {
|
if supported_mime == imgType.MIME.Value {
|
||||||
cache.insert_photo_type(path, supported_mime)
|
cache.insert_photo_type(path, supported_mime)
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -30,7 +30,7 @@ const albumQuery = gql`
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
}
|
}
|
||||||
original {
|
highRes {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ const photoQuery = gql`
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
}
|
}
|
||||||
original {
|
highRes {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export const PresentPhoto = ({ photo, imageLoaded, ...otherProps }) => {
|
||||||
<StyledPhoto src={photo.thumbnail.url} />
|
<StyledPhoto src={photo.thumbnail.url} />
|
||||||
<StyledPhoto
|
<StyledPhoto
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
src={photo.original.url}
|
src={photo.highRes.url}
|
||||||
onLoad={e => {
|
onLoad={e => {
|
||||||
e.target.style.display = 'initial'
|
e.target.style.display = 'initial'
|
||||||
imageLoaded && imageLoaded()
|
imageLoaded && imageLoaded()
|
||||||
|
|
|
@ -13,7 +13,7 @@ const photoQuery = gql`
|
||||||
photo(id: $id) {
|
photo(id: $id) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
original {
|
highRes {
|
||||||
url
|
url
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
|
@ -22,9 +22,7 @@ const photoQuery = gql`
|
||||||
camera
|
camera
|
||||||
maker
|
maker
|
||||||
lens
|
lens
|
||||||
dateShot {
|
dateShot
|
||||||
formatted
|
|
||||||
}
|
|
||||||
fileSize
|
fileSize
|
||||||
exposure
|
exposure
|
||||||
aperture
|
aperture
|
||||||
|
@ -77,7 +75,7 @@ const SidebarContent = ({ photo, hidePreview }) => {
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
|
||||||
exif.dateShot = new Date(exif.dateShot.formatted).toLocaleString()
|
exif.dateShot = new Date(exif.dateShot).toLocaleString()
|
||||||
|
|
||||||
exifItems = exifKeys.map(key => (
|
exifItems = exifKeys.map(key => (
|
||||||
<SidebarItem key={key} name={exifNameLookup[key]} value={exif[key]} />
|
<SidebarItem key={key} name={exifNameLookup[key]} value={exif[key]} />
|
||||||
|
@ -86,7 +84,7 @@ const SidebarContent = ({ photo, hidePreview }) => {
|
||||||
|
|
||||||
let previewUrl = null
|
let previewUrl = null
|
||||||
if (photo) {
|
if (photo) {
|
||||||
if (photo.original) previewUrl = photo.original.url
|
if (photo.highRes) previewUrl = photo.highRes.url
|
||||||
else if (photo.thumbnail) previewUrl = photo.thumbnail.url
|
else if (photo.thumbnail) previewUrl = photo.thumbnail.url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ const SidebarDownload = ({ photoId }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
SidebarDownload.propTypes = {
|
SidebarDownload.propTypes = {
|
||||||
photoId: PropTypes.string,
|
photoId: PropTypes.number,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SidebarDownload
|
export default SidebarDownload
|
||||||
|
|
Loading…
Reference in New Issue