Work on shares
This commit is contained in:
parent
5a0f03268d
commit
687b4f4f7f
|
@ -2,11 +2,11 @@ CREATE TABLE IF NOT EXISTS share_token (
|
|||
token_id int AUTO_INCREMENT,
|
||||
value char(24) NOT NULL UNIQUE,
|
||||
owner_id int NOT NULL,
|
||||
expire timestamp,
|
||||
password varchar(256) NOT NULL,
|
||||
expire timestamp NULL DEFAULT NULL,
|
||||
password varchar(256),
|
||||
album_id int,
|
||||
photo_id int,
|
||||
|
||||
PRIMARY KEY (token_id),
|
||||
CHECK (album_id IS NOT NULL OR photo_id IS NOT NULL)
|
||||
PRIMARY KEY (token_id)
|
||||
-- CHECK (album_id IS NOT NULL OR photo_id IS NOT NULL)
|
||||
);
|
||||
|
|
|
@ -25,6 +25,7 @@ func SetupDatabase() *sql.DB {
|
|||
|
||||
queryValues := address.Query()
|
||||
queryValues.Add("multiStatements", "true")
|
||||
queryValues.Add("parseTime", "true")
|
||||
|
||||
address.RawQuery = queryValues.Encode()
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ type ComplexityRoot struct {
|
|||
ParentAlbum func(childComplexity int) int
|
||||
Path func(childComplexity int) int
|
||||
Photos func(childComplexity int, filter *models.Filter) int
|
||||
Shares func(childComplexity int) int
|
||||
SubAlbums func(childComplexity int, filter *models.Filter) int
|
||||
Thumbnail func(childComplexity int) int
|
||||
Title func(childComplexity int) int
|
||||
|
@ -114,15 +115,14 @@ type ComplexityRoot struct {
|
|||
}
|
||||
|
||||
Query struct {
|
||||
Album func(childComplexity int, id int) int
|
||||
AlbumShares func(childComplexity int, id int, password *string) int
|
||||
MyAlbums func(childComplexity int, filter *models.Filter) int
|
||||
MyPhotos func(childComplexity int, filter *models.Filter) int
|
||||
MyUser func(childComplexity int) int
|
||||
Photo func(childComplexity int, id int) int
|
||||
PhotoShares func(childComplexity int, id int, password *string) int
|
||||
SiteInfo func(childComplexity int) int
|
||||
Users func(childComplexity int, filter *models.Filter) int
|
||||
Album func(childComplexity int, id int) int
|
||||
MyAlbums func(childComplexity int, filter *models.Filter) int
|
||||
MyPhotos func(childComplexity int, filter *models.Filter) int
|
||||
MyUser func(childComplexity int) int
|
||||
Photo func(childComplexity int, id int) int
|
||||
ShareToken func(childComplexity int, token string, password *string) int
|
||||
SiteInfo func(childComplexity int) int
|
||||
Users func(childComplexity int, filter *models.Filter) int
|
||||
}
|
||||
|
||||
ScannerResult struct {
|
||||
|
@ -160,6 +160,7 @@ type AlbumResolver interface {
|
|||
Owner(ctx context.Context, obj *models.Album) (*models.User, error)
|
||||
|
||||
Thumbnail(ctx context.Context, obj *models.Album) (*models.Photo, error)
|
||||
Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error)
|
||||
}
|
||||
type MutationResolver interface {
|
||||
AuthorizeUser(ctx context.Context, username string, password string) (*models.AuthorizeResult, error)
|
||||
|
@ -186,8 +187,7 @@ type QueryResolver interface {
|
|||
Album(ctx context.Context, id int) (*models.Album, error)
|
||||
MyPhotos(ctx context.Context, filter *models.Filter) ([]*models.Photo, error)
|
||||
Photo(ctx context.Context, id int) (*models.Photo, error)
|
||||
AlbumShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error)
|
||||
PhotoShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error)
|
||||
ShareToken(ctx context.Context, token string, password *string) (*models.ShareToken, error)
|
||||
}
|
||||
type ShareTokenResolver interface {
|
||||
Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error)
|
||||
|
@ -251,6 +251,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Album.Photos(childComplexity, args["filter"].(*models.Filter)), true
|
||||
|
||||
case "Album.shares":
|
||||
if e.complexity.Album.Shares == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Album.Shares(childComplexity), true
|
||||
|
||||
case "Album.subAlbums":
|
||||
if e.complexity.Album.SubAlbums == nil {
|
||||
break
|
||||
|
@ -564,18 +571,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Query.Album(childComplexity, args["id"].(int)), true
|
||||
|
||||
case "Query.albumShares":
|
||||
if e.complexity.Query.AlbumShares == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Query_albumShares_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Query.AlbumShares(childComplexity, args["id"].(int), args["password"].(*string)), true
|
||||
|
||||
case "Query.myAlbums":
|
||||
if e.complexity.Query.MyAlbums == nil {
|
||||
break
|
||||
|
@ -619,17 +614,17 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Query.Photo(childComplexity, args["id"].(int)), true
|
||||
|
||||
case "Query.photoShares":
|
||||
if e.complexity.Query.PhotoShares == nil {
|
||||
case "Query.shareToken":
|
||||
if e.complexity.Query.ShareToken == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Query_photoShares_args(context.TODO(), rawArgs)
|
||||
args, err := ec.field_Query_shareToken_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Query.PhotoShares(childComplexity, args["id"].(int), args["password"].(*string)), true
|
||||
return e.complexity.Query.ShareToken(childComplexity, args["token"].(string), args["password"].(*string)), true
|
||||
|
||||
case "Query.siteInfo":
|
||||
if e.complexity.Query.SiteInfo == nil {
|
||||
|
@ -851,8 +846,7 @@ type Query {
|
|||
"Get photo by id, user must own the photo or be admin"
|
||||
photo(id: Int!): Photo!
|
||||
|
||||
albumShares(id: Int!, password: String): [ShareToken!]!
|
||||
photoShares(id: Int!, password: String): [ShareToken!]!
|
||||
shareToken(token: String!, password: String): ShareToken!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
@ -942,7 +936,7 @@ type Album {
|
|||
"An image in this album used for previewing this album"
|
||||
thumbnail: Photo
|
||||
|
||||
# shares: [ShareToken]
|
||||
shares: [ShareToken]
|
||||
}
|
||||
|
||||
type PhotoURL {
|
||||
|
@ -1204,28 +1198,6 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_albumShares_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 int
|
||||
if tmp, ok := rawArgs["id"]; ok {
|
||||
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["id"] = arg0
|
||||
var arg1 *string
|
||||
if tmp, ok := rawArgs["password"]; ok {
|
||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["password"] = arg1
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_album_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
|
@ -1268,28 +1240,6 @@ func (ec *executionContext) field_Query_myPhotos_args(ctx context.Context, rawAr
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_photoShares_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 int
|
||||
if tmp, ok := rawArgs["id"]; ok {
|
||||
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["id"] = arg0
|
||||
var arg1 *string
|
||||
if tmp, ok := rawArgs["password"]; ok {
|
||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["password"] = arg1
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
|
@ -1304,6 +1254,28 @@ func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_shareToken_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 string
|
||||
if tmp, ok := rawArgs["token"]; ok {
|
||||
arg0, err = ec.unmarshalNString2string(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["token"] = arg0
|
||||
var arg1 *string
|
||||
if tmp, ok := rawArgs["password"]; ok {
|
||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["password"] = arg1
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
|
@ -1658,6 +1630,40 @@ func (ec *executionContext) _Album_thumbnail(ctx context.Context, field graphql.
|
|||
return ec.marshalOPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Album_shares(ctx context.Context, field graphql.CollectedField, obj *models.Album) (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: "Album",
|
||||
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.Album().Shares(rctx, obj)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*models.ShareToken)
|
||||
rctx.Result = res
|
||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||
return ec.marshalOShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _AuthorizeResult_success(ctx context.Context, field graphql.CollectedField, obj *models.AuthorizeResult) (ret graphql.Marshaler) {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
defer func() {
|
||||
|
@ -3261,7 +3267,7 @@ func (ec *executionContext) _Query_photo(ctx context.Context, field graphql.Coll
|
|||
return ec.marshalNPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
func (ec *executionContext) _Query_shareToken(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
|
@ -3278,7 +3284,7 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
|||
}
|
||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.field_Query_albumShares_args(ctx, rawArgs)
|
||||
args, err := ec.field_Query_shareToken_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
|
@ -3287,7 +3293,7 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
|||
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.Query().AlbumShares(rctx, args["id"].(int), args["password"].(*string))
|
||||
return ec.resolvers.Query().ShareToken(rctx, args["token"].(string), args["password"].(*string))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
|
@ -3299,54 +3305,10 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
|||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*models.ShareToken)
|
||||
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) _Query_photoShares(ctx context.Context, field graphql.CollectedField) (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: "Query",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: true,
|
||||
}
|
||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.field_Query_photoShares_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
rctx.Args = args
|
||||
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.Query().PhotoShares(rctx, args["id"].(int), args["password"].(*string))
|
||||
})
|
||||
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)
|
||||
return ec.marshalNShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
|
@ -5269,6 +5231,17 @@ func (ec *executionContext) _Album(ctx context.Context, sel ast.SelectionSet, ob
|
|||
res = ec._Album_thumbnail(ctx, field, obj)
|
||||
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._Album_shares(ctx, field, obj)
|
||||
return res
|
||||
})
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -5710,7 +5683,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
|||
}
|
||||
return res
|
||||
})
|
||||
case "albumShares":
|
||||
case "shareToken":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
|
@ -5718,21 +5691,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
|||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Query_albumShares(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
})
|
||||
case "photoShares":
|
||||
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._Query_photoShares(ctx, field)
|
||||
res = ec._Query_shareToken(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
|
@ -6905,6 +6864,46 @@ func (ec *executionContext) marshalOShareToken2githubᚗcomᚋviktorstrateᚋpho
|
|||
return ec._ShareToken(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx context.Context, sel ast.SelectionSet, v []*models.ShareToken) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
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.marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
} else {
|
||||
go f(i)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx context.Context, sel ast.SelectionSet, v *models.ShareToken) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ShareToken struct {
|
||||
TokenID int
|
||||
|
@ -19,3 +22,27 @@ func (share *ShareToken) Token() string {
|
|||
func (share *ShareToken) ID() int {
|
||||
return share.TokenID
|
||||
}
|
||||
|
||||
func NewShareTokenFromRow(row *sql.Row) (*ShareToken, error) {
|
||||
token := ShareToken{}
|
||||
|
||||
if err := row.Scan(&token.TokenID, &token.Value, &token.OwnerID, &token.Expire, &token.Password, &token.AlbumID, &token.PhotoID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
func NewShareTokensFromRows(rows *sql.Rows) ([]*ShareToken, error) {
|
||||
tokens := make([]*ShareToken, 0)
|
||||
|
||||
for rows.Next() {
|
||||
var token ShareToken
|
||||
if err := rows.Scan(&token.TokenID, &token.Value, &token.OwnerID, &token.Expire, &token.Password, &token.AlbumID, &token.PhotoID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokens = append(tokens, &token)
|
||||
}
|
||||
|
||||
return tokens, nil
|
||||
}
|
||||
|
|
|
@ -117,3 +117,13 @@ func (r *albumResolver) ParentAlbum(ctx context.Context, obj *models.Album) (*mo
|
|||
func (r *albumResolver) Owner(ctx context.Context, obj *models.Album) (*models.User, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (r *albumResolver) Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error) {
|
||||
rows, err := r.Database.Query("SELECT * FROM share_token WHERE album_id = ?", obj.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return models.NewShareTokensFromRows(rows)
|
||||
}
|
||||
|
|
|
@ -54,14 +54,22 @@ func (r *shareTokenResolver) Photo(ctx context.Context, obj *models.ShareToken)
|
|||
return photo, nil
|
||||
}
|
||||
|
||||
func (r *queryResolver) AlbumShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error) {
|
||||
log.Println("Query AlbumShares: not implemented")
|
||||
func (r *queryResolver) ShareToken(ctx context.Context, token string, password *string) (*models.ShareToken, error) {
|
||||
|
||||
tokens := make([]*models.ShareToken, 0)
|
||||
return tokens, nil
|
||||
row := r.Database.QueryRow("SELECT * FROM share_token WHERE value = ? AND (password = ? OR password IS NULL)", token, password)
|
||||
result, err := models.NewShareTokenFromRow(row)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *queryResolver) PhotoShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error) {
|
||||
func (r *queryResolver) PhotoShares(ctx context.Context, token string, password *string) ([]*models.ShareToken, error) {
|
||||
log.Println("Query PhotoShares: not implemented")
|
||||
|
||||
tokens := make([]*models.ShareToken, 0)
|
||||
|
|
|
@ -32,8 +32,7 @@ type Query {
|
|||
"Get photo by id, user must own the photo or be admin"
|
||||
photo(id: Int!): Photo!
|
||||
|
||||
albumShares(id: Int!, password: String): [ShareToken!]!
|
||||
photoShares(id: Int!, password: String): [ShareToken!]!
|
||||
shareToken(token: String!, password: String): ShareToken!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
@ -123,7 +122,7 @@ type Album {
|
|||
"An image in this album used for previewing this album"
|
||||
thumbnail: Photo
|
||||
|
||||
# shares: [ShareToken]
|
||||
shares: [ShareToken]
|
||||
}
|
||||
|
||||
type PhotoURL {
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Query } from 'react-apollo'
|
|||
import gql from 'graphql-tag'
|
||||
|
||||
const tokenQuery = gql`
|
||||
query SharePageToken($token: Int!) {
|
||||
query SharePageToken($token: String!) {
|
||||
shareToken(token: $token) {
|
||||
token
|
||||
album {
|
||||
|
@ -28,7 +28,7 @@ const tokenQuery = gql`
|
|||
fragment AlbumProps on Album {
|
||||
id
|
||||
title
|
||||
photos(orderBy: title_desc) {
|
||||
photos(filter: { order_by: "title", order_direction: DESC }) {
|
||||
...PhotoProps
|
||||
}
|
||||
}
|
||||
|
@ -41,16 +41,14 @@ const tokenQuery = gql`
|
|||
width
|
||||
height
|
||||
}
|
||||
original {
|
||||
highRes {
|
||||
url
|
||||
}
|
||||
exif {
|
||||
camera
|
||||
maker
|
||||
lens
|
||||
dateShot {
|
||||
formatted
|
||||
}
|
||||
dateShot
|
||||
fileSize
|
||||
exposure
|
||||
aperture
|
||||
|
|
|
@ -9,10 +9,13 @@ export async function fetchProtectedImage(src, { signal } = { signal: null }) {
|
|||
return imageCache[src]
|
||||
}
|
||||
|
||||
let headers = {}
|
||||
if (localStorage.getItem('token')) {
|
||||
headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`
|
||||
}
|
||||
|
||||
let image = await fetch(src, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
headers,
|
||||
signal,
|
||||
})
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ const AlbumSidebar = ({ albumId }) => {
|
|||
}
|
||||
|
||||
AlbumSidebar.propTypes = {
|
||||
albumId: PropTypes.string.isRequired,
|
||||
albumId: PropTypes.number.isRequired,
|
||||
}
|
||||
|
||||
export default AlbumSidebar
|
||||
|
|
|
@ -7,26 +7,28 @@ import copy from 'copy-to-clipboard'
|
|||
|
||||
const sharePhotoQuery = gql`
|
||||
query sidbarGetPhotoShares($id: Int!) {
|
||||
photoShares(id: $id) {
|
||||
token
|
||||
photo(id: $id) {
|
||||
id
|
||||
shares {
|
||||
token
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const shareAlbumQuery = gql`
|
||||
query sidbarGetAlbumShares($id: Int!) {
|
||||
albumShares(id: $id) {
|
||||
token
|
||||
album(id: $id) {
|
||||
id
|
||||
shares {
|
||||
token
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const addPhotoShareMutation = gql`
|
||||
mutation sidebarPhotoAddShare(
|
||||
$id: Int!
|
||||
$password: String
|
||||
$expire: _Neo4jDateInput
|
||||
) {
|
||||
mutation sidebarPhotoAddShare($id: Int!, $password: String, $expire: Time) {
|
||||
sharePhoto(photoId: $id, password: $password, expire: $expire) {
|
||||
token
|
||||
}
|
||||
|
@ -34,11 +36,7 @@ const addPhotoShareMutation = gql`
|
|||
`
|
||||
|
||||
const addAlbumShareMutation = gql`
|
||||
mutation sidebarAlbumAddShare(
|
||||
$id: Int!
|
||||
$password: String
|
||||
$expire: _Neo4jDateInput
|
||||
) {
|
||||
mutation sidebarAlbumAddShare($id: Int!, $password: String, $expire: Time) {
|
||||
shareAlbum(albumId: $id, password: $password, expire: $expire) {
|
||||
token
|
||||
}
|
||||
|
@ -71,9 +69,9 @@ const SidebarShare = ({ photo, album }) => {
|
|||
<Query query={query} variables={{ id }}>
|
||||
{({ loading, error, data, refetch }) => {
|
||||
if (loading) return <div>Loading...</div>
|
||||
if (error) return <div>Error: {error}</div>
|
||||
if (error) return <div>Error: {error.message}</div>
|
||||
|
||||
let shares = isPhoto ? data.photoShares : data.albumShares
|
||||
let shares = isPhoto ? data.photo.shares : data.album.shares
|
||||
|
||||
const rows = shares.map(share => (
|
||||
<Table.Row key={share.token}>
|
||||
|
|
Loading…
Reference in New Issue