Merge pull request #530 from photoview/improved-timeline
Improved timeline
This commit is contained in:
commit
77e1a45f0c
|
@ -37,6 +37,7 @@ yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
# vscode
|
# IDEs
|
||||||
|
.vscode
|
||||||
__debug_bin
|
__debug_bin
|
||||||
.idea
|
.idea
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"eslint.workingDirectories": ["ui"]
|
|
||||||
}
|
|
|
@ -38,6 +38,8 @@ models:
|
||||||
resolver: true
|
resolver: true
|
||||||
type:
|
type:
|
||||||
resolver: true
|
resolver: true
|
||||||
|
album:
|
||||||
|
resolver: true
|
||||||
MediaURL:
|
MediaURL:
|
||||||
model: github.com/photoview/photoview/api/graphql/models.MediaURL
|
model: github.com/photoview/photoview/api/graphql/models.MediaURL
|
||||||
MediaEXIF:
|
MediaEXIF:
|
||||||
|
|
|
@ -98,6 +98,7 @@ type ComplexityRoot struct {
|
||||||
|
|
||||||
Media struct {
|
Media struct {
|
||||||
Album func(childComplexity int) int
|
Album func(childComplexity int) int
|
||||||
|
Date func(childComplexity int) int
|
||||||
Downloads func(childComplexity int) int
|
Downloads func(childComplexity int) int
|
||||||
Exif func(childComplexity int) int
|
Exif func(childComplexity int) int
|
||||||
Faces func(childComplexity int) int
|
Faces func(childComplexity int) int
|
||||||
|
@ -188,7 +189,7 @@ type ComplexityRoot struct {
|
||||||
MyFaceGroups func(childComplexity int, paginate *models.Pagination) int
|
MyFaceGroups func(childComplexity int, paginate *models.Pagination) int
|
||||||
MyMedia func(childComplexity int, order *models.Ordering, paginate *models.Pagination) int
|
MyMedia func(childComplexity int, order *models.Ordering, paginate *models.Pagination) int
|
||||||
MyMediaGeoJSON func(childComplexity int) int
|
MyMediaGeoJSON func(childComplexity int) int
|
||||||
MyTimeline func(childComplexity int, paginate *models.Pagination, onlyFavorites *bool) int
|
MyTimeline func(childComplexity int, paginate *models.Pagination, onlyFavorites *bool, fromDate *time.Time) int
|
||||||
MyUser func(childComplexity int) int
|
MyUser func(childComplexity int) int
|
||||||
MyUserPreferences func(childComplexity int) int
|
MyUserPreferences func(childComplexity int) int
|
||||||
Search func(childComplexity int, query string, limitMedia *int, limitAlbums *int) int
|
Search func(childComplexity int, query string, limitMedia *int, limitAlbums *int) int
|
||||||
|
@ -287,11 +288,12 @@ type MediaResolver interface {
|
||||||
Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
||||||
HighRes(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
HighRes(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
||||||
VideoWeb(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
VideoWeb(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
|
||||||
|
Album(ctx context.Context, obj *models.Media) (*models.Album, error)
|
||||||
Exif(ctx context.Context, obj *models.Media) (*models.MediaEXIF, error)
|
Exif(ctx context.Context, obj *models.Media) (*models.MediaEXIF, error)
|
||||||
|
|
||||||
Favorite(ctx context.Context, obj *models.Media) (bool, error)
|
Favorite(ctx context.Context, obj *models.Media) (bool, error)
|
||||||
Type(ctx context.Context, obj *models.Media) (models.MediaType, error)
|
Type(ctx context.Context, obj *models.Media) (models.MediaType, error)
|
||||||
|
|
||||||
Shares(ctx context.Context, obj *models.Media) ([]*models.ShareToken, error)
|
Shares(ctx context.Context, obj *models.Media) ([]*models.ShareToken, error)
|
||||||
Downloads(ctx context.Context, obj *models.Media) ([]*models.MediaDownload, error)
|
Downloads(ctx context.Context, obj *models.Media) ([]*models.MediaDownload, error)
|
||||||
Faces(ctx context.Context, obj *models.Media) ([]*models.ImageFace, error)
|
Faces(ctx context.Context, obj *models.Media) ([]*models.ImageFace, error)
|
||||||
|
@ -332,7 +334,7 @@ type QueryResolver interface {
|
||||||
MyMedia(ctx context.Context, order *models.Ordering, paginate *models.Pagination) ([]*models.Media, error)
|
MyMedia(ctx context.Context, order *models.Ordering, paginate *models.Pagination) ([]*models.Media, error)
|
||||||
Media(ctx context.Context, id int, tokenCredentials *models.ShareTokenCredentials) (*models.Media, error)
|
Media(ctx context.Context, id int, tokenCredentials *models.ShareTokenCredentials) (*models.Media, error)
|
||||||
MediaList(ctx context.Context, ids []int) ([]*models.Media, error)
|
MediaList(ctx context.Context, ids []int) ([]*models.Media, error)
|
||||||
MyTimeline(ctx context.Context, paginate *models.Pagination, onlyFavorites *bool) ([]*models.TimelineGroup, error)
|
MyTimeline(ctx context.Context, paginate *models.Pagination, onlyFavorites *bool, fromDate *time.Time) ([]*models.Media, error)
|
||||||
MyMediaGeoJSON(ctx context.Context) (interface{}, error)
|
MyMediaGeoJSON(ctx context.Context) (interface{}, error)
|
||||||
MapboxToken(ctx context.Context) (*string, error)
|
MapboxToken(ctx context.Context) (*string, error)
|
||||||
ShareToken(ctx context.Context, credentials models.ShareTokenCredentials) (*models.ShareToken, error)
|
ShareToken(ctx context.Context, credentials models.ShareTokenCredentials) (*models.ShareToken, error)
|
||||||
|
@ -567,6 +569,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Media.Album(childComplexity), true
|
return e.complexity.Media.Album(childComplexity), true
|
||||||
|
|
||||||
|
case "Media.date":
|
||||||
|
if e.complexity.Media.Date == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Media.Date(childComplexity), true
|
||||||
|
|
||||||
case "Media.downloads":
|
case "Media.downloads":
|
||||||
if e.complexity.Media.Downloads == nil {
|
if e.complexity.Media.Downloads == nil {
|
||||||
break
|
break
|
||||||
|
@ -1226,7 +1235,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.Query.MyTimeline(childComplexity, args["paginate"].(*models.Pagination), args["onlyFavorites"].(*bool)), true
|
return e.complexity.Query.MyTimeline(childComplexity, args["paginate"].(*models.Pagination), args["onlyFavorites"].(*bool), args["fromDate"].(*time.Time)), true
|
||||||
|
|
||||||
case "Query.myUser":
|
case "Query.myUser":
|
||||||
if e.complexity.Query.MyUser == nil {
|
if e.complexity.Query.MyUser == nil {
|
||||||
|
@ -1723,7 +1732,15 @@ type Query {
|
||||||
"Get a list of media by their ids, user must own the media or be admin"
|
"Get a list of media by their ids, user must own the media or be admin"
|
||||||
mediaList(ids: [ID!]!): [Media!]!
|
mediaList(ids: [ID!]!): [Media!]!
|
||||||
|
|
||||||
myTimeline(paginate: Pagination, onlyFavorites: Boolean): [TimelineGroup!]! @isAuthorized
|
"""
|
||||||
|
Get a list of media, ordered first by day, then by album if multiple media was found for the same day.
|
||||||
|
"""
|
||||||
|
myTimeline(
|
||||||
|
paginate: Pagination,
|
||||||
|
onlyFavorites: Boolean,
|
||||||
|
"Only fetch media that is older than this date"
|
||||||
|
fromDate: Time
|
||||||
|
): [Media!]! @isAuthorized
|
||||||
|
|
||||||
"Get media owned by the logged in user, returned in GeoJson format"
|
"Get media owned by the logged in user, returned in GeoJson format"
|
||||||
myMediaGeoJson: Any! @isAuthorized
|
myMediaGeoJson: Any! @isAuthorized
|
||||||
|
@ -1980,6 +1997,8 @@ type Media {
|
||||||
videoMetadata: VideoMetadata
|
videoMetadata: VideoMetadata
|
||||||
favorite: Boolean!
|
favorite: Boolean!
|
||||||
type: MediaType!
|
type: MediaType!
|
||||||
|
"The date the image was shot or the date it was imported as a fallback"
|
||||||
|
date: Time!
|
||||||
|
|
||||||
shares: [ShareToken!]!
|
shares: [ShareToken!]!
|
||||||
downloads: [MediaDownload!]!
|
downloads: [MediaDownload!]!
|
||||||
|
@ -2843,6 +2862,15 @@ func (ec *executionContext) field_Query_myTimeline_args(ctx context.Context, raw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args["onlyFavorites"] = arg1
|
args["onlyFavorites"] = arg1
|
||||||
|
var arg2 *time.Time
|
||||||
|
if tmp, ok := rawArgs["fromDate"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fromDate"))
|
||||||
|
arg2, err = ec.unmarshalOTime2ᚖtimeᚐTime(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["fromDate"] = arg2
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4067,14 +4095,14 @@ func (ec *executionContext) _Media_album(ctx context.Context, field graphql.Coll
|
||||||
Object: "Media",
|
Object: "Media",
|
||||||
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) {
|
||||||
ctx = rctx // use context from middleware stack in children
|
ctx = rctx // use context from middleware stack in children
|
||||||
return obj.Album, nil
|
return ec.resolvers.Media().Album(rctx, obj)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
|
@ -4086,9 +4114,9 @@ func (ec *executionContext) _Media_album(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.marshalNAlbum2githubᚗ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) _Media_exif(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Media_exif(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
|
@ -4225,6 +4253,41 @@ func (ec *executionContext) _Media_type(ctx context.Context, field graphql.Colle
|
||||||
return ec.marshalNMediaType2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaType(ctx, field.Selections, res)
|
return ec.marshalNMediaType2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaType(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Media_date(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "Media",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Date(), nil
|
||||||
|
})
|
||||||
|
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.(time.Time)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Media_shares(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Media_shares(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
@ -7112,7 +7175,7 @@ func (ec *executionContext) _Query_myTimeline(ctx context.Context, field graphql
|
||||||
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 ec.resolvers.Query().MyTimeline(rctx, args["paginate"].(*models.Pagination), args["onlyFavorites"].(*bool))
|
return ec.resolvers.Query().MyTimeline(rctx, args["paginate"].(*models.Pagination), args["onlyFavorites"].(*bool), args["fromDate"].(*time.Time))
|
||||||
}
|
}
|
||||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||||
if ec.directives.IsAuthorized == nil {
|
if ec.directives.IsAuthorized == nil {
|
||||||
|
@ -7128,10 +7191,10 @@ func (ec *executionContext) _Query_myTimeline(ctx context.Context, field graphql
|
||||||
if tmp == nil {
|
if tmp == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if data, ok := tmp.([]*models.TimelineGroup); ok {
|
if data, ok := tmp.([]*models.Media); 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.TimelineGroup`, tmp)
|
return nil, fmt.Errorf(`unexpected type %T from directive, should be []*github.com/photoview/photoview/api/graphql/models.Media`, tmp)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
|
@ -7143,9 +7206,9 @@ func (ec *executionContext) _Query_myTimeline(ctx context.Context, field graphql
|
||||||
}
|
}
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.([]*models.TimelineGroup)
|
res := resTmp.([]*models.Media)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNTimelineGroup2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐTimelineGroupᚄ(ctx, field.Selections, res)
|
return ec.marshalNMedia2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaᚄ(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Query_myMediaGeoJson(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Query_myMediaGeoJson(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
@ -10576,10 +10639,19 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
case "album":
|
case "album":
|
||||||
out.Values[i] = ec._Media_album(ctx, field, obj)
|
field := field
|
||||||
if out.Values[i] == graphql.Null {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
atomic.AddUint32(&invalids, 1)
|
defer func() {
|
||||||
}
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._Media_album(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
case "exif":
|
case "exif":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
@ -10621,6 +10693,11 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
case "date":
|
||||||
|
out.Values[i] = ec._Media_date(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
case "shares":
|
case "shares":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
@ -12466,53 +12543,6 @@ func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context, sel as
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNTimelineGroup2ᚕᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐTimelineGroupᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.TimelineGroup) 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.marshalNTimelineGroup2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐTimelineGroup(ctx, sel, v[i])
|
|
||||||
}
|
|
||||||
if isLen1 {
|
|
||||||
f(i)
|
|
||||||
} else {
|
|
||||||
go f(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNTimelineGroup2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐTimelineGroup(ctx context.Context, sel ast.SelectionSet, v *models.TimelineGroup) graphql.Marshaler {
|
|
||||||
if v == nil {
|
|
||||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
return ec._TimelineGroup(ctx, sel, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNUser2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx context.Context, sel ast.SelectionSet, v models.User) graphql.Marshaler {
|
func (ec *executionContext) marshalNUser2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx context.Context, sel ast.SelectionSet, v models.User) graphql.Marshaler {
|
||||||
return ec._User(ctx, sel, &v)
|
return ec._User(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/photoview/photoview/api/graphql/models"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MyMedia(db *gorm.DB, user *models.User, order *models.Ordering, paginate *models.Pagination) ([]*models.Media, error) {
|
||||||
|
if err := user.FillAlbums(db); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := db.Where("media.album_id IN (SELECT user_albums.album_id FROM user_albums WHERE user_albums.user_id = ?)", user.ID)
|
||||||
|
query = models.FormatSQL(query, order, paginate)
|
||||||
|
|
||||||
|
var media []*models.Media
|
||||||
|
if err := query.Find(&media).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return media, nil
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package actions_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/photoview/photoview/api/graphql/models"
|
||||||
|
"github.com/photoview/photoview/api/graphql/models/actions"
|
||||||
|
"github.com/photoview/photoview/api/test_utils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMyMedia(t *testing.T) {
|
||||||
|
db := test_utils.DatabaseTest(t)
|
||||||
|
|
||||||
|
password := "1234"
|
||||||
|
user, err := models.RegisterUser(db, "user", &password, false)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
rootAlbum := models.Album{
|
||||||
|
Title: "root",
|
||||||
|
Path: "/photos",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, db.Save(&rootAlbum).Error)
|
||||||
|
|
||||||
|
childAlbum := models.Album{
|
||||||
|
Title: "subalbum",
|
||||||
|
Path: "/photos/subalbum",
|
||||||
|
ParentAlbumID: &rootAlbum.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, db.Save(&childAlbum).Error)
|
||||||
|
|
||||||
|
assert.NoError(t, db.Model(&user).Association("Albums").Append(&rootAlbum))
|
||||||
|
assert.NoError(t, db.Model(&user).Association("Albums").Append(&childAlbum))
|
||||||
|
|
||||||
|
media := []models.Media{
|
||||||
|
{
|
||||||
|
Title: "pic1",
|
||||||
|
Path: "/photos/pic1",
|
||||||
|
AlbumID: rootAlbum.ID,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "pic2",
|
||||||
|
Path: "/photos/pic2",
|
||||||
|
AlbumID: rootAlbum.ID,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "pic3",
|
||||||
|
Path: "/photos/subalbum/pic3",
|
||||||
|
AlbumID: childAlbum.ID,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "pic4",
|
||||||
|
Path: "/photos/subalbum/pic4",
|
||||||
|
AlbumID: childAlbum.ID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, db.Save(&media).Error)
|
||||||
|
|
||||||
|
anotherUser, err := models.RegisterUser(db, "user2", &password, false)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
anotherAlbum := models.Album{
|
||||||
|
Title: "AnotherAlbum",
|
||||||
|
Path: "/another",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, db.Save(&anotherAlbum).Error)
|
||||||
|
|
||||||
|
anotherMedia := models.Media{
|
||||||
|
Title: "anotherPic",
|
||||||
|
Path: "/another/anotherPic",
|
||||||
|
AlbumID: anotherAlbum.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, db.Save(&anotherMedia).Error)
|
||||||
|
|
||||||
|
assert.NoError(t, db.Model(&anotherUser).Association("Albums").Append(&anotherAlbum))
|
||||||
|
|
||||||
|
t.Run("Simple query", func(t *testing.T) {
|
||||||
|
myMedia, err := actions.MyMedia(db, user, nil, nil)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, myMedia, 4)
|
||||||
|
})
|
||||||
|
}
|
|
@ -45,6 +45,10 @@ func (m *Media) BeforeSave(tx *gorm.DB) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Media) Date() time.Time {
|
||||||
|
return m.DateShot
|
||||||
|
}
|
||||||
|
|
||||||
type MediaType string
|
type MediaType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
api "github.com/photoview/photoview/api/graphql"
|
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/graphql/models/actions"
|
||||||
"github.com/photoview/photoview/api/scanner/face_detection"
|
"github.com/photoview/photoview/api/scanner/face_detection"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
|
@ -19,29 +20,7 @@ func (r *queryResolver) MyMedia(ctx context.Context, order *models.Ordering, pag
|
||||||
return nil, errors.New("unauthorized")
|
return nil, errors.New("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.FillAlbums(r.Database); err != nil {
|
return actions.MyMedia(r.Database, user, order, paginate)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userAlbumIDs := make([]int, len(user.Albums))
|
|
||||||
for i, album := range user.Albums {
|
|
||||||
userAlbumIDs[i] = album.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
var media []*models.Media
|
|
||||||
|
|
||||||
query := r.Database.
|
|
||||||
Joins("Album").
|
|
||||||
Where("albums.id IN (?)", userAlbumIDs).
|
|
||||||
Where("media.id IN (?)", r.Database.Model(&models.MediaURL{}).Select("id").Where("media_url.media_id = media.id"))
|
|
||||||
|
|
||||||
query = models.FormatSQL(query, order, paginate)
|
|
||||||
|
|
||||||
if err := query.Find(&media).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return media, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Media(ctx context.Context, id int, tokenCredentials *models.ShareTokenCredentials) (*models.Media, error) {
|
func (r *queryResolver) Media(ctx context.Context, id int, tokenCredentials *models.ShareTokenCredentials) (*models.Media, error) {
|
||||||
|
@ -115,6 +94,15 @@ func (r *mediaResolver) Type(ctx context.Context, media *models.Media) (models.M
|
||||||
return formattedType, nil
|
return formattedType, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mediaResolver) Album(ctx context.Context, obj *models.Media) (*models.Album, error) {
|
||||||
|
var album models.Album
|
||||||
|
err := r.Database.Find(&album, obj.AlbumID).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &album, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *mediaResolver) Shares(ctx context.Context, media *models.Media) ([]*models.ShareToken, error) {
|
func (r *mediaResolver) Shares(ctx context.Context, media *models.Media) ([]*models.ShareToken, error) {
|
||||||
var shareTokens []*models.ShareToken
|
var shareTokens []*models.ShareToken
|
||||||
if err := r.Database.Where("media_id = ?", media.ID).Find(&shareTokens).Error; err != nil {
|
if err := r.Database.Where("media_id = ?", media.ID).Find(&shareTokens).Error; err != nil {
|
||||||
|
|
|
@ -2,135 +2,40 @@ package resolvers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/photoview/photoview/api/database"
|
|
||||||
"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"
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Pagination, onlyFavorites *bool) ([]*models.TimelineGroup, error) {
|
func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Pagination, onlyFavorites *bool, fromDate *time.Time) ([]*models.Media, error) {
|
||||||
user := auth.UserFromContext(ctx)
|
user := auth.UserFromContext(ctx)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return nil, auth.ErrUnauthorized
|
return nil, auth.ErrUnauthorized
|
||||||
}
|
}
|
||||||
|
|
||||||
var timelineGroups []*models.TimelineGroup
|
query := r.Database.
|
||||||
|
Joins("JOIN albums ON media.album_id = albums.id").
|
||||||
|
Where("albums.id IN (?)", r.Database.Table("user_albums").Select("user_albums.album_id").Where("user_id = ?", user.ID)).
|
||||||
|
Order("YEAR(media.date_shot) DESC").
|
||||||
|
Order("MONTH(media.date_shot) DESC").
|
||||||
|
Order("DAY(media.date_shot) DESC").
|
||||||
|
Order("albums.title ASC")
|
||||||
|
|
||||||
transactionError := r.Database.Transaction(func(tx *gorm.DB) error {
|
if fromDate != nil {
|
||||||
// album_id, year, month, day
|
query = query.Where("media.date_shot < ?", fromDate)
|
||||||
daysQuery := tx.Select(
|
|
||||||
"albums.id AS album_id",
|
|
||||||
fmt.Sprintf("%s AS year", database.DateExtract(tx, database.DateCompYear, "media.date_shot")),
|
|
||||||
fmt.Sprintf("%s AS month", database.DateExtract(tx, database.DateCompMonth, "media.date_shot")),
|
|
||||||
fmt.Sprintf("%s AS day", database.DateExtract(tx, database.DateCompDay, "media.date_shot")),
|
|
||||||
).
|
|
||||||
Table("media").
|
|
||||||
Joins("JOIN albums ON media.album_id = albums.id").
|
|
||||||
Where("albums.id IN (?)", tx.Table("user_albums").Select("user_albums.album_id").Where("user_id = ?", user.ID))
|
|
||||||
|
|
||||||
if onlyFavorites != nil && *onlyFavorites == true {
|
|
||||||
daysQuery.Where("media.id IN (?)", tx.Table("user_media_data").Select("user_media_data.media_id").Where("user_media_data.user_id = ?", user.ID).Where("user_media_data.favorite = 1"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if paginate != nil {
|
|
||||||
if paginate.Limit != nil {
|
|
||||||
daysQuery.Limit(*paginate.Limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
if paginate.Offset != nil {
|
|
||||||
daysQuery.Offset(*paginate.Offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := daysQuery.Group("albums.id").Group(
|
|
||||||
fmt.Sprintf("%s, %s, %s",
|
|
||||||
database.DateExtract(tx, database.DateCompYear, "media.date_shot"),
|
|
||||||
database.DateExtract(tx, database.DateCompMonth, "media.date_shot"),
|
|
||||||
database.DateExtract(tx, database.DateCompDay, "media.date_shot")),
|
|
||||||
).
|
|
||||||
Order(
|
|
||||||
fmt.Sprintf("%s DESC, %s DESC, %s DESC",
|
|
||||||
database.DateExtract(tx, database.DateCompYear, "media.date_shot"),
|
|
||||||
database.DateExtract(tx, database.DateCompMonth, "media.date_shot"),
|
|
||||||
database.DateExtract(tx, database.DateCompDay, "media.date_shot")),
|
|
||||||
).Rows()
|
|
||||||
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type group struct {
|
|
||||||
albumID int
|
|
||||||
year int
|
|
||||||
month int
|
|
||||||
day int
|
|
||||||
}
|
|
||||||
|
|
||||||
dbGroups := make([]group, 0)
|
|
||||||
|
|
||||||
for rows.Next() {
|
|
||||||
var g group
|
|
||||||
rows.Scan(&g.albumID, &g.year, &g.month, &g.day)
|
|
||||||
dbGroups = append(dbGroups, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
timelineGroups = make([]*models.TimelineGroup, len(dbGroups))
|
|
||||||
|
|
||||||
for i, group := range dbGroups {
|
|
||||||
|
|
||||||
// Fill album
|
|
||||||
var groupAlbum models.Album
|
|
||||||
if err := tx.First(&groupAlbum, group.albumID).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill media
|
|
||||||
var groupMedia []*models.Media
|
|
||||||
mediaQuery := tx.Model(&models.Media{}).
|
|
||||||
Where("album_id = ?", group.albumID).
|
|
||||||
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompYear, "media.date_shot")), group.year).
|
|
||||||
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompMonth, "media.date_shot")), group.month).
|
|
||||||
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompDay, "media.date_shot")), group.day).
|
|
||||||
Order("date_shot DESC")
|
|
||||||
|
|
||||||
if onlyFavorites != nil && *onlyFavorites == true {
|
|
||||||
mediaQuery.Where("media.id IN (?)", tx.Table("user_media_data").Select("user_media_data.media_id").Where("user_media_data.user_id = ?", user.ID).Where("user_media_data.favorite = 1"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mediaQuery.Limit(5).Find(&groupMedia).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total media count
|
|
||||||
var totalMedia int64
|
|
||||||
if err := mediaQuery.Count(&totalMedia).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var date time.Time = groupMedia[0].DateShot
|
|
||||||
date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
|
|
||||||
|
|
||||||
timelineGroup := models.TimelineGroup{
|
|
||||||
Album: &groupAlbum,
|
|
||||||
Media: groupMedia,
|
|
||||||
MediaTotal: int(totalMedia),
|
|
||||||
Date: date,
|
|
||||||
}
|
|
||||||
|
|
||||||
timelineGroups[i] = &timelineGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if transactionError != nil {
|
|
||||||
return nil, transactionError
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return timelineGroups, nil
|
if onlyFavorites != nil && *onlyFavorites == true {
|
||||||
|
query = query.Where("media.id IN (?)", r.Database.Table("user_media_data").Select("user_media_data.media_id").Where("user_media_data.user_id = ?", user.ID).Where("user_media_data.favorite = 1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
query = models.FormatSQL(query, nil, paginate)
|
||||||
|
|
||||||
|
var media []*models.Media
|
||||||
|
if err := query.Find(&media).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return media, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,15 @@ type Query {
|
||||||
"Get a list of media by their ids, user must own the media or be admin"
|
"Get a list of media by their ids, user must own the media or be admin"
|
||||||
mediaList(ids: [ID!]!): [Media!]!
|
mediaList(ids: [ID!]!): [Media!]!
|
||||||
|
|
||||||
myTimeline(paginate: Pagination, onlyFavorites: Boolean): [TimelineGroup!]! @isAuthorized
|
"""
|
||||||
|
Get a list of media, ordered first by day, then by album if multiple media was found for the same day.
|
||||||
|
"""
|
||||||
|
myTimeline(
|
||||||
|
paginate: Pagination,
|
||||||
|
onlyFavorites: Boolean,
|
||||||
|
"Only fetch media that is older than this date"
|
||||||
|
fromDate: Time
|
||||||
|
): [Media!]! @isAuthorized
|
||||||
|
|
||||||
"Get media owned by the logged in user, returned in GeoJson format"
|
"Get media owned by the logged in user, returned in GeoJson format"
|
||||||
myMediaGeoJson: Any! @isAuthorized
|
myMediaGeoJson: Any! @isAuthorized
|
||||||
|
@ -318,6 +326,8 @@ type Media {
|
||||||
videoMetadata: VideoMetadata
|
videoMetadata: VideoMetadata
|
||||||
favorite: Boolean!
|
favorite: Boolean!
|
||||||
type: MediaType!
|
type: MediaType!
|
||||||
|
"The date the image was shot or the date it was imported as a fallback"
|
||||||
|
date: Time!
|
||||||
|
|
||||||
shares: [ShareToken!]!
|
shares: [ShareToken!]!
|
||||||
downloads: [MediaDownload!]!
|
downloads: [MediaDownload!]!
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -63,7 +63,7 @@
|
||||||
"lint:types": "tsc --noemit",
|
"lint:types": "tsc --noemit",
|
||||||
"jest": "craco test --setupFilesAfterEnv ./testing/setupTests.ts",
|
"jest": "craco test --setupFilesAfterEnv ./testing/setupTests.ts",
|
||||||
"jest:ci": "CI=true craco test --setupFilesAfterEnv ./testing/setupTests.ts --verbose --ci --coverage",
|
"jest:ci": "CI=true craco test --setupFilesAfterEnv ./testing/setupTests.ts --verbose --ci --coverage",
|
||||||
"genSchemaTypes": "npx apollo client:codegen --target=typescript --globalTypesFile=src/__generated__/globalTypes.ts",
|
"genSchemaTypes": "apollo client:codegen --target=typescript --globalTypesFile=src/__generated__/globalTypes.ts",
|
||||||
"extractTranslations": "i18next -c i18next-parser.config.js",
|
"extractTranslations": "i18next -c i18next-parser.config.js",
|
||||||
"prepare": "(cd .. && npx husky install)"
|
"prepare": "(cd .. && npx husky install)"
|
||||||
},
|
},
|
||||||
|
@ -75,7 +75,9 @@
|
||||||
"husky": "^6.0.0",
|
"husky": "^6.0.0",
|
||||||
"i18next-parser": "^4.2.0",
|
"i18next-parser": "^4.2.0",
|
||||||
"lint-staged": "^11.0.1",
|
"lint-staged": "^11.0.1",
|
||||||
"tsc-files": "^1.1.2"
|
"tsc-files": "^1.1.2",
|
||||||
|
"apollo": "2.33.4",
|
||||||
|
"apollo-language-server": "1.26.3"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
|
|
|
@ -3,102 +3,102 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { OrderDirection, MediaType } from './../../../__generated__/globalTypes'
|
import { OrderDirection, MediaType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: albumQuery
|
// GraphQL query operation: albumQuery
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface albumQuery_album_subAlbums_thumbnail_thumbnail {
|
export interface albumQuery_album_subAlbums_thumbnail_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_subAlbums_thumbnail {
|
export interface albumQuery_album_subAlbums_thumbnail {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: albumQuery_album_subAlbums_thumbnail_thumbnail | null
|
thumbnail: albumQuery_album_subAlbums_thumbnail_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_subAlbums {
|
export interface albumQuery_album_subAlbums {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* An image in this album used for previewing this album
|
* An image in this album used for previewing this album
|
||||||
*/
|
*/
|
||||||
thumbnail: albumQuery_album_subAlbums_thumbnail | null
|
thumbnail: albumQuery_album_subAlbums_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_media_thumbnail {
|
export interface albumQuery_album_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_media_highRes {
|
export interface albumQuery_album_media_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_media_videoWeb {
|
export interface albumQuery_album_media_videoWeb {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album_media {
|
export interface albumQuery_album_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: albumQuery_album_media_thumbnail | null
|
thumbnail: albumQuery_album_media_thumbnail | null;
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: albumQuery_album_media_highRes | null
|
highRes: albumQuery_album_media_highRes | null;
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: albumQuery_album_media_videoWeb | null
|
videoWeb: albumQuery_album_media_videoWeb | null;
|
||||||
favorite: boolean
|
favorite: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery_album {
|
export interface albumQuery_album {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* The albums contained in this album
|
* The albums contained in this album
|
||||||
*/
|
*/
|
||||||
subAlbums: albumQuery_album_subAlbums[]
|
subAlbums: albumQuery_album_subAlbums[];
|
||||||
/**
|
/**
|
||||||
* The media inside this album
|
* The media inside this album
|
||||||
*/
|
*/
|
||||||
media: albumQuery_album_media[]
|
media: albumQuery_album_media[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQuery {
|
export interface albumQuery {
|
||||||
|
@ -106,14 +106,14 @@ export interface albumQuery {
|
||||||
* Get album by id, user must own the album or be admin
|
* Get album by id, user must own the album or be admin
|
||||||
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
album: albumQuery_album
|
album: albumQuery_album;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumQueryVariables {
|
export interface albumQueryVariables {
|
||||||
id: string
|
id: string;
|
||||||
onlyFavorites?: boolean | null
|
onlyFavorites?: boolean | null;
|
||||||
mediaOrderBy?: string | null
|
mediaOrderBy?: string | null;
|
||||||
mediaOrderDirection?: OrderDirection | null
|
mediaOrderDirection?: OrderDirection | null;
|
||||||
limit?: number | null
|
limit?: number | null;
|
||||||
offset?: number | null
|
offset?: number | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,35 +8,35 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface getMyAlbums_myAlbums_thumbnail_thumbnail {
|
export interface getMyAlbums_myAlbums_thumbnail_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface getMyAlbums_myAlbums_thumbnail {
|
export interface getMyAlbums_myAlbums_thumbnail {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: getMyAlbums_myAlbums_thumbnail_thumbnail | null
|
thumbnail: getMyAlbums_myAlbums_thumbnail_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface getMyAlbums_myAlbums {
|
export interface getMyAlbums_myAlbums {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* An image in this album used for previewing this album
|
* An image in this album used for previewing this album
|
||||||
*/
|
*/
|
||||||
thumbnail: getMyAlbums_myAlbums_thumbnail | null
|
thumbnail: getMyAlbums_myAlbums_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface getMyAlbums {
|
export interface getMyAlbums {
|
||||||
/**
|
/**
|
||||||
* List of albums owned by the logged in user.
|
* List of albums owned by the logged in user.
|
||||||
*/
|
*/
|
||||||
myAlbums: getMyAlbums_myAlbums[]
|
myAlbums: getMyAlbums_myAlbums[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CheckInitialSetup_siteInfo {
|
export interface CheckInitialSetup_siteInfo {
|
||||||
__typename: 'SiteInfo'
|
__typename: "SiteInfo";
|
||||||
/**
|
/**
|
||||||
* Whether or not the initial setup wizard should be shown
|
* Whether or not the initial setup wizard should be shown
|
||||||
*/
|
*/
|
||||||
initialSetup: boolean
|
initialSetup: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckInitialSetup {
|
export interface CheckInitialSetup {
|
||||||
siteInfo: CheckInitialSetup_siteInfo
|
siteInfo: CheckInitialSetup_siteInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,80 +3,80 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MediaType } from './../../../../__generated__/globalTypes'
|
import { MediaType } from "./../../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: singleFaceGroup
|
// GraphQL query operation: singleFaceGroup
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup_imageFaces_rectangle {
|
export interface singleFaceGroup_faceGroup_imageFaces_rectangle {
|
||||||
__typename: 'FaceRectangle'
|
__typename: "FaceRectangle";
|
||||||
minX: number
|
minX: number;
|
||||||
maxX: number
|
maxX: number;
|
||||||
minY: number
|
minY: number;
|
||||||
maxY: number
|
maxY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup_imageFaces_media_thumbnail {
|
export interface singleFaceGroup_faceGroup_imageFaces_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup_imageFaces_media_highRes {
|
export interface singleFaceGroup_faceGroup_imageFaces_media_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup_imageFaces_media {
|
export interface singleFaceGroup_faceGroup_imageFaces_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: singleFaceGroup_faceGroup_imageFaces_media_thumbnail | null
|
thumbnail: singleFaceGroup_faceGroup_imageFaces_media_thumbnail | null;
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: singleFaceGroup_faceGroup_imageFaces_media_highRes | null
|
highRes: singleFaceGroup_faceGroup_imageFaces_media_highRes | null;
|
||||||
favorite: boolean
|
favorite: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup_imageFaces {
|
export interface singleFaceGroup_faceGroup_imageFaces {
|
||||||
__typename: 'ImageFace'
|
__typename: "ImageFace";
|
||||||
id: string
|
id: string;
|
||||||
rectangle: singleFaceGroup_faceGroup_imageFaces_rectangle
|
rectangle: singleFaceGroup_faceGroup_imageFaces_rectangle;
|
||||||
media: singleFaceGroup_faceGroup_imageFaces_media
|
media: singleFaceGroup_faceGroup_imageFaces_media;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup_faceGroup {
|
export interface singleFaceGroup_faceGroup {
|
||||||
__typename: 'FaceGroup'
|
__typename: "FaceGroup";
|
||||||
id: string
|
id: string;
|
||||||
label: string | null
|
label: string | null;
|
||||||
imageFaces: singleFaceGroup_faceGroup_imageFaces[]
|
imageFaces: singleFaceGroup_faceGroup_imageFaces[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroup {
|
export interface singleFaceGroup {
|
||||||
faceGroup: singleFaceGroup_faceGroup
|
faceGroup: singleFaceGroup_faceGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface singleFaceGroupVariables {
|
export interface singleFaceGroupVariables {
|
||||||
id: string
|
id: string;
|
||||||
limit: number
|
limit: number;
|
||||||
offset: number
|
offset: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,59 +8,59 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface myFaces_myFaceGroups_imageFaces_rectangle {
|
export interface myFaces_myFaceGroups_imageFaces_rectangle {
|
||||||
__typename: 'FaceRectangle'
|
__typename: "FaceRectangle";
|
||||||
minX: number
|
minX: number;
|
||||||
maxX: number
|
maxX: number;
|
||||||
minY: number
|
minY: number;
|
||||||
maxY: number
|
maxY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFaces_myFaceGroups_imageFaces_media_thumbnail {
|
export interface myFaces_myFaceGroups_imageFaces_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFaces_myFaceGroups_imageFaces_media {
|
export interface myFaces_myFaceGroups_imageFaces_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: myFaces_myFaceGroups_imageFaces_media_thumbnail | null
|
thumbnail: myFaces_myFaceGroups_imageFaces_media_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFaces_myFaceGroups_imageFaces {
|
export interface myFaces_myFaceGroups_imageFaces {
|
||||||
__typename: 'ImageFace'
|
__typename: "ImageFace";
|
||||||
id: string
|
id: string;
|
||||||
rectangle: myFaces_myFaceGroups_imageFaces_rectangle
|
rectangle: myFaces_myFaceGroups_imageFaces_rectangle;
|
||||||
media: myFaces_myFaceGroups_imageFaces_media
|
media: myFaces_myFaceGroups_imageFaces_media;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFaces_myFaceGroups {
|
export interface myFaces_myFaceGroups {
|
||||||
__typename: 'FaceGroup'
|
__typename: "FaceGroup";
|
||||||
id: string
|
id: string;
|
||||||
label: string | null
|
label: string | null;
|
||||||
imageFaceCount: number
|
imageFaceCount: number;
|
||||||
imageFaces: myFaces_myFaceGroups_imageFaces[]
|
imageFaces: myFaces_myFaceGroups_imageFaces[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFaces {
|
export interface myFaces {
|
||||||
myFaceGroups: myFaces_myFaceGroups[]
|
myFaceGroups: myFaces_myFaceGroups[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myFacesVariables {
|
export interface myFacesVariables {
|
||||||
limit?: number | null
|
limit?: number | null;
|
||||||
offset?: number | null
|
offset?: number | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,86 +3,86 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MediaType } from './../../../__generated__/globalTypes'
|
import { MediaType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: placePageQueryMedia
|
// GraphQL query operation: placePageQueryMedia
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface placePageQueryMedia_mediaList_thumbnail {
|
export interface placePageQueryMedia_mediaList_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface placePageQueryMedia_mediaList_highRes {
|
export interface placePageQueryMedia_mediaList_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface placePageQueryMedia_mediaList_videoWeb {
|
export interface placePageQueryMedia_mediaList_videoWeb {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface placePageQueryMedia_mediaList {
|
export interface placePageQueryMedia_mediaList {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: placePageQueryMedia_mediaList_thumbnail | null
|
thumbnail: placePageQueryMedia_mediaList_thumbnail | null;
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: placePageQueryMedia_mediaList_highRes | null
|
highRes: placePageQueryMedia_mediaList_highRes | null;
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: placePageQueryMedia_mediaList_videoWeb | null
|
videoWeb: placePageQueryMedia_mediaList_videoWeb | null;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface placePageQueryMedia {
|
export interface placePageQueryMedia {
|
||||||
/**
|
/**
|
||||||
* Get a list of media by their ids, user must own the media or be admin
|
* Get a list of media by their ids, user must own the media or be admin
|
||||||
*/
|
*/
|
||||||
mediaList: placePageQueryMedia_mediaList[]
|
mediaList: placePageQueryMedia_mediaList[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface placePageQueryMediaVariables {
|
export interface placePageQueryMediaVariables {
|
||||||
mediaIDs: string[]
|
mediaIDs: string[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface changeUserPassword_updateUser {
|
export interface changeUserPassword_updateUser {
|
||||||
__typename: 'User'
|
__typename: "User";
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface changeUserPassword {
|
export interface changeUserPassword {
|
||||||
updateUser: changeUserPassword_updateUser
|
updateUser: changeUserPassword_updateUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface changeUserPasswordVariables {
|
export interface changeUserPasswordVariables {
|
||||||
userId: string
|
userId: string;
|
||||||
password: string
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface createUser_createUser {
|
export interface createUser_createUser {
|
||||||
__typename: 'User'
|
__typename: "User";
|
||||||
id: string
|
id: string;
|
||||||
username: string
|
username: string;
|
||||||
admin: boolean
|
admin: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface createUser {
|
export interface createUser {
|
||||||
createUser: createUser_createUser
|
createUser: createUser_createUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface createUserVariables {
|
export interface createUserVariables {
|
||||||
username: string
|
username: string;
|
||||||
admin: boolean
|
admin: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface deleteUser_deleteUser {
|
export interface deleteUser_deleteUser {
|
||||||
__typename: 'User'
|
__typename: "User";
|
||||||
id: string
|
id: string;
|
||||||
username: string
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface deleteUser {
|
export interface deleteUser {
|
||||||
deleteUser: deleteUser_deleteUser
|
deleteUser: deleteUser_deleteUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface deleteUserVariables {
|
export interface deleteUserVariables {
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,18 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface updateUser_updateUser {
|
export interface updateUser_updateUser {
|
||||||
__typename: 'User'
|
__typename: "User";
|
||||||
id: string
|
id: string;
|
||||||
username: string
|
username: string;
|
||||||
admin: boolean
|
admin: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface updateUser {
|
export interface updateUser {
|
||||||
updateUser: updateUser_updateUser
|
updateUser: updateUser_updateUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface updateUserVariables {
|
export interface updateUserVariables {
|
||||||
id: string
|
id: string;
|
||||||
username?: string | null
|
username?: string | null;
|
||||||
admin?: boolean | null
|
admin?: boolean | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,22 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { LanguageTranslation } from './../../../__generated__/globalTypes'
|
import { LanguageTranslation } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: changeUserPreferences
|
// GraphQL mutation operation: changeUserPreferences
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface changeUserPreferences_changeUserPreferences {
|
export interface changeUserPreferences_changeUserPreferences {
|
||||||
__typename: 'UserPreferences'
|
__typename: "UserPreferences";
|
||||||
id: string
|
id: string;
|
||||||
language: LanguageTranslation | null
|
language: LanguageTranslation | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface changeUserPreferences {
|
export interface changeUserPreferences {
|
||||||
changeUserPreferences: changeUserPreferences_changeUserPreferences
|
changeUserPreferences: changeUserPreferences_changeUserPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface changeUserPreferencesVariables {
|
export interface changeUserPreferencesVariables {
|
||||||
language?: string | null
|
language?: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,18 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { LanguageTranslation } from './../../../__generated__/globalTypes'
|
import { LanguageTranslation } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: myUserPreferences
|
// GraphQL query operation: myUserPreferences
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface myUserPreferences_myUserPreferences {
|
export interface myUserPreferences_myUserPreferences {
|
||||||
__typename: 'UserPreferences'
|
__typename: "UserPreferences";
|
||||||
id: string
|
id: string;
|
||||||
language: LanguageTranslation | null
|
language: LanguageTranslation | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myUserPreferences {
|
export interface myUserPreferences {
|
||||||
myUserPreferences: myUserPreferences_myUserPreferences
|
myUserPreferences: myUserPreferences_myUserPreferences;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,172 +3,172 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MediaType } from './../../../__generated__/globalTypes'
|
import { MediaType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: SharePageToken
|
// GraphQL query operation: SharePageToken
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_album {
|
export interface SharePageToken_shareToken_album {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_thumbnail {
|
export interface SharePageToken_shareToken_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_downloads_mediaUrl {
|
export interface SharePageToken_shareToken_media_downloads_mediaUrl {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
/**
|
/**
|
||||||
* The file size of the resource in bytes
|
* The file size of the resource in bytes
|
||||||
*/
|
*/
|
||||||
fileSize: number
|
fileSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_downloads {
|
export interface SharePageToken_shareToken_media_downloads {
|
||||||
__typename: 'MediaDownload'
|
__typename: "MediaDownload";
|
||||||
title: string
|
title: string;
|
||||||
mediaUrl: SharePageToken_shareToken_media_downloads_mediaUrl
|
mediaUrl: SharePageToken_shareToken_media_downloads_mediaUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_highRes {
|
export interface SharePageToken_shareToken_media_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_videoWeb {
|
export interface SharePageToken_shareToken_media_videoWeb {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media_exif {
|
export interface SharePageToken_shareToken_media_exif {
|
||||||
__typename: 'MediaEXIF'
|
__typename: "MediaEXIF";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* The model name of the camera
|
* The model name of the camera
|
||||||
*/
|
*/
|
||||||
camera: string | null
|
camera: string | null;
|
||||||
/**
|
/**
|
||||||
* The maker of the camera
|
* The maker of the camera
|
||||||
*/
|
*/
|
||||||
maker: string | null
|
maker: string | null;
|
||||||
/**
|
/**
|
||||||
* The name of the lens
|
* The name of the lens
|
||||||
*/
|
*/
|
||||||
lens: string | null
|
lens: string | null;
|
||||||
dateShot: any | null
|
dateShot: any | null;
|
||||||
/**
|
/**
|
||||||
* The exposure time of the image
|
* The exposure time of the image
|
||||||
*/
|
*/
|
||||||
exposure: number | null
|
exposure: number | null;
|
||||||
/**
|
/**
|
||||||
* The aperature stops of the image
|
* The aperature stops of the image
|
||||||
*/
|
*/
|
||||||
aperture: number | null
|
aperture: number | null;
|
||||||
/**
|
/**
|
||||||
* The ISO setting of the image
|
* The ISO setting of the image
|
||||||
*/
|
*/
|
||||||
iso: number | null
|
iso: number | null;
|
||||||
/**
|
/**
|
||||||
* The focal length of the lens, when the image was taken
|
* The focal length of the lens, when the image was taken
|
||||||
*/
|
*/
|
||||||
focalLength: number | null
|
focalLength: number | null;
|
||||||
/**
|
/**
|
||||||
* A formatted description of the flash settings, when the image was taken
|
* A formatted description of the flash settings, when the image was taken
|
||||||
*/
|
*/
|
||||||
flash: number | null
|
flash: number | null;
|
||||||
/**
|
/**
|
||||||
* An index describing the mode for adjusting the exposure of the image
|
* An index describing the mode for adjusting the exposure of the image
|
||||||
*/
|
*/
|
||||||
exposureProgram: number | null
|
exposureProgram: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken_media {
|
export interface SharePageToken_shareToken_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: SharePageToken_shareToken_media_thumbnail | null
|
thumbnail: SharePageToken_shareToken_media_thumbnail | null;
|
||||||
downloads: SharePageToken_shareToken_media_downloads[]
|
downloads: SharePageToken_shareToken_media_downloads[];
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: SharePageToken_shareToken_media_highRes | null
|
highRes: SharePageToken_shareToken_media_highRes | null;
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: SharePageToken_shareToken_media_videoWeb | null
|
videoWeb: SharePageToken_shareToken_media_videoWeb | null;
|
||||||
exif: SharePageToken_shareToken_media_exif | null
|
exif: SharePageToken_shareToken_media_exif | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken_shareToken {
|
export interface SharePageToken_shareToken {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
token: string
|
token: string;
|
||||||
/**
|
/**
|
||||||
* The album this token shares
|
* The album this token shares
|
||||||
*/
|
*/
|
||||||
album: SharePageToken_shareToken_album | null
|
album: SharePageToken_shareToken_album | null;
|
||||||
/**
|
/**
|
||||||
* The media this token shares
|
* The media this token shares
|
||||||
*/
|
*/
|
||||||
media: SharePageToken_shareToken_media | null
|
media: SharePageToken_shareToken_media | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageToken {
|
export interface SharePageToken {
|
||||||
shareToken: SharePageToken_shareToken
|
shareToken: SharePageToken_shareToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharePageTokenVariables {
|
export interface SharePageTokenVariables {
|
||||||
token: string
|
token: string;
|
||||||
password?: string | null
|
password?: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,179 +3,179 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { OrderDirection, MediaType } from './../../../__generated__/globalTypes'
|
import { OrderDirection, MediaType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: shareAlbumQuery
|
// GraphQL query operation: shareAlbumQuery
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_subAlbums_thumbnail_thumbnail {
|
export interface shareAlbumQuery_album_subAlbums_thumbnail_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_subAlbums_thumbnail {
|
export interface shareAlbumQuery_album_subAlbums_thumbnail {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: shareAlbumQuery_album_subAlbums_thumbnail_thumbnail | null
|
thumbnail: shareAlbumQuery_album_subAlbums_thumbnail_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_subAlbums {
|
export interface shareAlbumQuery_album_subAlbums {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* An image in this album used for previewing this album
|
* An image in this album used for previewing this album
|
||||||
*/
|
*/
|
||||||
thumbnail: shareAlbumQuery_album_subAlbums_thumbnail | null
|
thumbnail: shareAlbumQuery_album_subAlbums_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_thumbnail {
|
export interface shareAlbumQuery_album_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_downloads_mediaUrl {
|
export interface shareAlbumQuery_album_media_downloads_mediaUrl {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
/**
|
/**
|
||||||
* The file size of the resource in bytes
|
* The file size of the resource in bytes
|
||||||
*/
|
*/
|
||||||
fileSize: number
|
fileSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_downloads {
|
export interface shareAlbumQuery_album_media_downloads {
|
||||||
__typename: 'MediaDownload'
|
__typename: "MediaDownload";
|
||||||
title: string
|
title: string;
|
||||||
mediaUrl: shareAlbumQuery_album_media_downloads_mediaUrl
|
mediaUrl: shareAlbumQuery_album_media_downloads_mediaUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_highRes {
|
export interface shareAlbumQuery_album_media_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_videoWeb {
|
export interface shareAlbumQuery_album_media_videoWeb {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media_exif {
|
export interface shareAlbumQuery_album_media_exif {
|
||||||
__typename: 'MediaEXIF'
|
__typename: "MediaEXIF";
|
||||||
/**
|
/**
|
||||||
* The model name of the camera
|
* The model name of the camera
|
||||||
*/
|
*/
|
||||||
camera: string | null
|
camera: string | null;
|
||||||
/**
|
/**
|
||||||
* The maker of the camera
|
* The maker of the camera
|
||||||
*/
|
*/
|
||||||
maker: string | null
|
maker: string | null;
|
||||||
/**
|
/**
|
||||||
* The name of the lens
|
* The name of the lens
|
||||||
*/
|
*/
|
||||||
lens: string | null
|
lens: string | null;
|
||||||
dateShot: any | null
|
dateShot: any | null;
|
||||||
/**
|
/**
|
||||||
* The exposure time of the image
|
* The exposure time of the image
|
||||||
*/
|
*/
|
||||||
exposure: number | null
|
exposure: number | null;
|
||||||
/**
|
/**
|
||||||
* The aperature stops of the image
|
* The aperature stops of the image
|
||||||
*/
|
*/
|
||||||
aperture: number | null
|
aperture: number | null;
|
||||||
/**
|
/**
|
||||||
* The ISO setting of the image
|
* The ISO setting of the image
|
||||||
*/
|
*/
|
||||||
iso: number | null
|
iso: number | null;
|
||||||
/**
|
/**
|
||||||
* The focal length of the lens, when the image was taken
|
* The focal length of the lens, when the image was taken
|
||||||
*/
|
*/
|
||||||
focalLength: number | null
|
focalLength: number | null;
|
||||||
/**
|
/**
|
||||||
* A formatted description of the flash settings, when the image was taken
|
* A formatted description of the flash settings, when the image was taken
|
||||||
*/
|
*/
|
||||||
flash: number | null
|
flash: number | null;
|
||||||
/**
|
/**
|
||||||
* An index describing the mode for adjusting the exposure of the image
|
* An index describing the mode for adjusting the exposure of the image
|
||||||
*/
|
*/
|
||||||
exposureProgram: number | null
|
exposureProgram: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album_media {
|
export interface shareAlbumQuery_album_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: shareAlbumQuery_album_media_thumbnail | null
|
thumbnail: shareAlbumQuery_album_media_thumbnail | null;
|
||||||
downloads: shareAlbumQuery_album_media_downloads[]
|
downloads: shareAlbumQuery_album_media_downloads[];
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: shareAlbumQuery_album_media_highRes | null
|
highRes: shareAlbumQuery_album_media_highRes | null;
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: shareAlbumQuery_album_media_videoWeb | null
|
videoWeb: shareAlbumQuery_album_media_videoWeb | null;
|
||||||
exif: shareAlbumQuery_album_media_exif | null
|
exif: shareAlbumQuery_album_media_exif | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery_album {
|
export interface shareAlbumQuery_album {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
/**
|
/**
|
||||||
* The albums contained in this album
|
* The albums contained in this album
|
||||||
*/
|
*/
|
||||||
subAlbums: shareAlbumQuery_album_subAlbums[]
|
subAlbums: shareAlbumQuery_album_subAlbums[];
|
||||||
/**
|
/**
|
||||||
* The media inside this album
|
* The media inside this album
|
||||||
*/
|
*/
|
||||||
media: shareAlbumQuery_album_media[]
|
media: shareAlbumQuery_album_media[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQuery {
|
export interface shareAlbumQuery {
|
||||||
|
@ -183,15 +183,15 @@ export interface shareAlbumQuery {
|
||||||
* Get album by id, user must own the album or be admin
|
* Get album by id, user must own the album or be admin
|
||||||
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
album: shareAlbumQuery_album
|
album: shareAlbumQuery_album;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface shareAlbumQueryVariables {
|
export interface shareAlbumQueryVariables {
|
||||||
id: string
|
id: string;
|
||||||
token: string
|
token: string;
|
||||||
password?: string | null
|
password?: string | null;
|
||||||
mediaOrderBy?: string | null
|
mediaOrderBy?: string | null;
|
||||||
mediaOrderDirection?: OrderDirection | null
|
mediaOrderDirection?: OrderDirection | null;
|
||||||
limit?: number | null
|
limit?: number | null;
|
||||||
offset?: number | null
|
offset?: number | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Layout from '../../components/layout/Layout'
|
import Layout from '../../components/layout/Layout'
|
||||||
import TimelineGallery from '../../components/timelineGallery/TimelineGallery'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import TimelineGallery from '../../components/timelineGallery/TimelineGallery'
|
||||||
|
|
||||||
const PhotosPage = () => {
|
const TimelinePage = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Layout title={t('photos_page.title', 'Photos')}>
|
<Layout title={t('photos_page.title', 'Timeline')}>
|
||||||
<TimelineGallery />
|
<TimelineGallery />
|
||||||
</Layout>
|
</Layout>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PhotosPage
|
export default TimelinePage
|
|
@ -8,34 +8,34 @@
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
||||||
export enum LanguageTranslation {
|
export enum LanguageTranslation {
|
||||||
Danish = 'Danish',
|
Danish = "Danish",
|
||||||
English = 'English',
|
English = "English",
|
||||||
French = 'French',
|
French = "French",
|
||||||
German = 'German',
|
German = "German",
|
||||||
Italian = 'Italian',
|
Italian = "Italian",
|
||||||
Polish = 'Polish',
|
Polish = "Polish",
|
||||||
Portuguese = 'Portuguese',
|
Portuguese = "Portuguese",
|
||||||
Russian = 'Russian',
|
Russian = "Russian",
|
||||||
SimplifiedChinese = 'SimplifiedChinese',
|
SimplifiedChinese = "SimplifiedChinese",
|
||||||
Spanish = 'Spanish',
|
Spanish = "Spanish",
|
||||||
Swedish = 'Swedish',
|
Swedish = "Swedish",
|
||||||
TraditionalChinese = 'TraditionalChinese',
|
TraditionalChinese = "TraditionalChinese",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MediaType {
|
export enum MediaType {
|
||||||
Photo = 'Photo',
|
Photo = "Photo",
|
||||||
Video = 'Video',
|
Video = "Video",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum NotificationType {
|
export enum NotificationType {
|
||||||
Close = 'Close',
|
Close = "Close",
|
||||||
Message = 'Message',
|
Message = "Message",
|
||||||
Progress = 'Progress',
|
Progress = "Progress",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OrderDirection {
|
export enum OrderDirection {
|
||||||
ASC = 'ASC',
|
ASC = "ASC",
|
||||||
DESC = 'DESC',
|
DESC = "DESC",
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
|
@ -3,18 +3,18 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { LanguageTranslation } from './globalTypes'
|
import { LanguageTranslation } from "./globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: siteTranslation
|
// GraphQL query operation: siteTranslation
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface siteTranslation_myUserPreferences {
|
export interface siteTranslation_myUserPreferences {
|
||||||
__typename: 'UserPreferences'
|
__typename: "UserPreferences";
|
||||||
id: string
|
id: string;
|
||||||
language: LanguageTranslation | null
|
language: LanguageTranslation | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface siteTranslation {
|
export interface siteTranslation {
|
||||||
myUserPreferences: siteTranslation_myUserPreferences
|
myUserPreferences: siteTranslation_myUserPreferences;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { ReactComponent as DirectionIcon } from './icons/direction-arrow.svg'
|
||||||
|
|
||||||
import Dropdown from '../../primitives/form/Dropdown'
|
import Dropdown from '../../primitives/form/Dropdown'
|
||||||
|
|
||||||
type FavoriteCheckboxProps = {
|
export type FavoriteCheckboxProps = {
|
||||||
onlyFavorites: boolean
|
onlyFavorites: boolean
|
||||||
setOnlyFavorites(favorites: boolean): void
|
setOnlyFavorites(favorites: boolean): void
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ const SortingOptions = ({ setOrdering, ordering }: SortingOptionsProps) => {
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend id="filter_group_sort-label" className="inline-block mb-1">
|
<legend id="filter_group_sort-label" className="inline-block mb-1">
|
||||||
<SortingIcon
|
<SortingIcon
|
||||||
className="inline-block align-baseline mr-1"
|
className="inline-block align-baseline mr-1 mt-1"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span>{t('album_filter.sort', 'Sort')}</span>
|
<span>{t('album_filter.sort', 'Sort')}</span>
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface albumPathQuery_album_path {
|
export interface albumPathQuery_album_path {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumPathQuery_album {
|
export interface albumPathQuery_album {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
path: albumPathQuery_album_path[]
|
path: albumPathQuery_album_path[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumPathQuery {
|
export interface albumPathQuery {
|
||||||
|
@ -24,9 +24,9 @@ export interface albumPathQuery {
|
||||||
* Get album by id, user must own the album or be admin
|
* Get album by id, user must own the album or be admin
|
||||||
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
album: albumPathQuery_album
|
album: albumPathQuery_album;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface albumPathQueryVariables {
|
export interface albumPathQueryVariables {
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ export const MainMenu = () => {
|
||||||
<div className="fixed w-full bottom-0 lg:bottom-auto lg:top-[84px] z-30 bg-white shadow-separator lg:shadow-none lg:w-[240px] lg:ml-8 lg:mr-5 flex-shrink-0">
|
<div className="fixed w-full bottom-0 lg:bottom-auto lg:top-[84px] z-30 bg-white shadow-separator lg:shadow-none lg:w-[240px] lg:ml-8 lg:mr-5 flex-shrink-0">
|
||||||
<ul className="flex justify-around py-2 px-2 max-w-lg mx-auto lg:flex-col lg:p-0">
|
<ul className="flex justify-around py-2 px-2 max-w-lg mx-auto lg:flex-col lg:p-0">
|
||||||
<MenuButton
|
<MenuButton
|
||||||
to="/photos"
|
to="/timeline"
|
||||||
exact
|
exact
|
||||||
label={t('sidemenu.photos', 'Timeline')}
|
label={t('sidemenu.photos', 'Timeline')}
|
||||||
background="#8ac5f4"
|
background="#8ac5f4"
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface adminQuery_myUser {
|
export interface adminQuery_myUser {
|
||||||
__typename: 'User'
|
__typename: "User";
|
||||||
admin: boolean
|
admin: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface adminQuery {
|
export interface adminQuery {
|
||||||
/**
|
/**
|
||||||
* Information about the currently logged in user
|
* Information about the currently logged in user
|
||||||
*/
|
*/
|
||||||
myUser: adminQuery_myUser
|
myUser: adminQuery_myUser;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface faceDetectionEnabled_siteInfo {
|
export interface faceDetectionEnabled_siteInfo {
|
||||||
__typename: 'SiteInfo'
|
__typename: "SiteInfo";
|
||||||
/**
|
/**
|
||||||
* Whether or not face detection is enabled and working
|
* Whether or not face detection is enabled and working
|
||||||
*/
|
*/
|
||||||
faceDetectionEnabled: boolean
|
faceDetectionEnabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface faceDetectionEnabled {
|
export interface faceDetectionEnabled {
|
||||||
siteInfo: faceDetectionEnabled_siteInfo
|
siteInfo: faceDetectionEnabled_siteInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,5 @@ export interface mapboxEnabledQuery {
|
||||||
/**
|
/**
|
||||||
* Get the mapbox api token, returns null if mapbox is not enabled
|
* Get the mapbox api token, returns null if mapbox is not enabled
|
||||||
*/
|
*/
|
||||||
mapboxToken: string | null
|
mapboxToken: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,27 +3,27 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { NotificationType } from './../../../__generated__/globalTypes'
|
import { NotificationType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL subscription operation: notificationSubscription
|
// GraphQL subscription operation: notificationSubscription
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface notificationSubscription_notification {
|
export interface notificationSubscription_notification {
|
||||||
__typename: 'Notification'
|
__typename: "Notification";
|
||||||
key: string
|
key: string;
|
||||||
type: NotificationType
|
type: NotificationType;
|
||||||
header: string
|
header: string;
|
||||||
content: string
|
content: string;
|
||||||
progress: number | null
|
progress: number | null;
|
||||||
positive: boolean
|
positive: boolean;
|
||||||
negative: boolean
|
negative: boolean;
|
||||||
/**
|
/**
|
||||||
* Time in milliseconds before the notification will close
|
* Time in milliseconds before the notification will close
|
||||||
*/
|
*/
|
||||||
timeout: number | null
|
timeout: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface notificationSubscription {
|
export interface notificationSubscription {
|
||||||
notification: notificationSubscription_notification
|
notification: notificationSubscription_notification;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ const Gallery = styled.div`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const PhotoFiller = styled.div`
|
export const PhotoFiller = styled.div`
|
||||||
height: 200px;
|
height: 200px;
|
||||||
flex-grow: 999999;
|
flex-grow: 999999;
|
||||||
`
|
`
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface markMediaFavorite_favoriteMedia {
|
export interface markMediaFavorite_favoriteMedia {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
favorite: boolean
|
favorite: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface markMediaFavorite {
|
export interface markMediaFavorite {
|
||||||
/**
|
/**
|
||||||
* Mark or unmark a media as being a favorite
|
* Mark or unmark a media as being a favorite
|
||||||
*/
|
*/
|
||||||
favoriteMedia: markMediaFavorite_favoriteMedia
|
favoriteMedia: markMediaFavorite_favoriteMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface markMediaFavoriteVariables {
|
export interface markMediaFavoriteVariables {
|
||||||
mediaId: string
|
mediaId: string;
|
||||||
favorite: boolean
|
favorite: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@ const AlbumsPage = React.lazy(
|
||||||
() => import('../../Pages/AllAlbumsPage/AlbumsPage')
|
() => import('../../Pages/AllAlbumsPage/AlbumsPage')
|
||||||
)
|
)
|
||||||
const AlbumPage = React.lazy(() => import('../../Pages/AlbumPage/AlbumPage'))
|
const AlbumPage = React.lazy(() => import('../../Pages/AlbumPage/AlbumPage'))
|
||||||
const PhotosPage = React.lazy(() => import('../../Pages/PhotosPage/PhotosPage'))
|
const TimelinePage = React.lazy(
|
||||||
|
() => import('../../Pages/TimelinePage/TimelinePage')
|
||||||
|
)
|
||||||
const PlacesPage = React.lazy(() => import('../../Pages/PlacesPage/PlacesPage'))
|
const PlacesPage = React.lazy(() => import('../../Pages/PlacesPage/PlacesPage'))
|
||||||
const SharePage = React.lazy(() => import('../../Pages/SharePage/SharePage'))
|
const SharePage = React.lazy(() => import('../../Pages/SharePage/SharePage'))
|
||||||
const PeoplePage = React.lazy(() => import('../../Pages/PeoplePage/PeoplePage'))
|
const PeoplePage = React.lazy(() => import('../../Pages/PeoplePage/PeoplePage'))
|
||||||
|
@ -49,11 +51,17 @@ const Routes = () => {
|
||||||
<Route path="/share" component={SharePage} />
|
<Route path="/share" component={SharePage} />
|
||||||
<AuthorizedRoute exact path="/albums" component={AlbumsPage} />
|
<AuthorizedRoute exact path="/albums" component={AlbumsPage} />
|
||||||
<AuthorizedRoute path="/album/:id" component={AlbumPage} />
|
<AuthorizedRoute path="/album/:id" component={AlbumPage} />
|
||||||
<AuthorizedRoute path="/photos" component={PhotosPage} />
|
<AuthorizedRoute path="/timeline" component={TimelinePage} />
|
||||||
<AuthorizedRoute path="/places" component={PlacesPage} />
|
<AuthorizedRoute path="/places" component={PlacesPage} />
|
||||||
<AuthorizedRoute path="/people/:person?" component={PeoplePage} />
|
<AuthorizedRoute path="/people/:person?" component={PeoplePage} />
|
||||||
<AuthorizedRoute path="/settings" component={SettingsPage} />
|
<AuthorizedRoute path="/settings" component={SettingsPage} />
|
||||||
<Route path="/" exact render={() => <Redirect to="/photos" />} />
|
<Route path="/" exact render={() => <Redirect to="/timeline" />} />
|
||||||
|
{/* For backwards compatibility */}
|
||||||
|
<Route
|
||||||
|
path="/photos"
|
||||||
|
exact
|
||||||
|
render={() => <Redirect to="/timeline" />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
render={() => (
|
render={() => (
|
||||||
<div>{t('routes.page_not_found', 'Page not found')}</div>
|
<div>{t('routes.page_not_found', 'Page not found')}</div>
|
||||||
|
|
|
@ -8,38 +8,38 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface resetAlbumCover_resetAlbumCover_thumbnail_thumbnail {
|
export interface resetAlbumCover_resetAlbumCover_thumbnail_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface resetAlbumCover_resetAlbumCover_thumbnail {
|
export interface resetAlbumCover_resetAlbumCover_thumbnail {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: resetAlbumCover_resetAlbumCover_thumbnail_thumbnail | null
|
thumbnail: resetAlbumCover_resetAlbumCover_thumbnail_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface resetAlbumCover_resetAlbumCover {
|
export interface resetAlbumCover_resetAlbumCover {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* An image in this album used for previewing this album
|
* An image in this album used for previewing this album
|
||||||
*/
|
*/
|
||||||
thumbnail: resetAlbumCover_resetAlbumCover_thumbnail | null
|
thumbnail: resetAlbumCover_resetAlbumCover_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface resetAlbumCover {
|
export interface resetAlbumCover {
|
||||||
/**
|
/**
|
||||||
* Reset the assigned cover photo for an album
|
* Reset the assigned cover photo for an album
|
||||||
*/
|
*/
|
||||||
resetAlbumCover: resetAlbumCover_resetAlbumCover
|
resetAlbumCover: resetAlbumCover_resetAlbumCover;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface resetAlbumCoverVariables {
|
export interface resetAlbumCoverVariables {
|
||||||
albumID: string
|
albumID: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,38 +8,38 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface setAlbumCover_setAlbumCover_thumbnail_thumbnail {
|
export interface setAlbumCover_setAlbumCover_thumbnail_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface setAlbumCover_setAlbumCover_thumbnail {
|
export interface setAlbumCover_setAlbumCover_thumbnail {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: setAlbumCover_setAlbumCover_thumbnail_thumbnail | null
|
thumbnail: setAlbumCover_setAlbumCover_thumbnail_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface setAlbumCover_setAlbumCover {
|
export interface setAlbumCover_setAlbumCover {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* An image in this album used for previewing this album
|
* An image in this album used for previewing this album
|
||||||
*/
|
*/
|
||||||
thumbnail: setAlbumCover_setAlbumCover_thumbnail | null
|
thumbnail: setAlbumCover_setAlbumCover_thumbnail | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface setAlbumCover {
|
export interface setAlbumCover {
|
||||||
/**
|
/**
|
||||||
* Assign a cover photo to an album
|
* Assign a cover photo to an album
|
||||||
*/
|
*/
|
||||||
setAlbumCover: setAlbumCover_setAlbumCover
|
setAlbumCover: setAlbumCover_setAlbumCover;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface setAlbumCoverVariables {
|
export interface setAlbumCoverVariables {
|
||||||
coverID: string
|
coverID: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarAlbumAddShare_shareAlbum {
|
export interface sidebarAlbumAddShare_shareAlbum {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
token: string
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarAlbumAddShare {
|
export interface sidebarAlbumAddShare {
|
||||||
/**
|
/**
|
||||||
* Generate share token for album
|
* Generate share token for album
|
||||||
*/
|
*/
|
||||||
shareAlbum: sidebarAlbumAddShare_shareAlbum
|
shareAlbum: sidebarAlbumAddShare_shareAlbum;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarAlbumAddShareVariables {
|
export interface sidebarAlbumAddShareVariables {
|
||||||
id: string
|
id: string;
|
||||||
password?: string | null
|
password?: string | null;
|
||||||
expire?: any | null
|
expire?: any | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarGetAlbumShares_album_shares {
|
export interface sidebarGetAlbumShares_album_shares {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
id: string
|
id: string;
|
||||||
token: string
|
token: string;
|
||||||
/**
|
/**
|
||||||
* Whether or not a password is needed to access the share
|
* Whether or not a password is needed to access the share
|
||||||
*/
|
*/
|
||||||
hasPassword: boolean
|
hasPassword: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetAlbumShares_album {
|
export interface sidebarGetAlbumShares_album {
|
||||||
__typename: 'Album'
|
__typename: "Album";
|
||||||
id: string
|
id: string;
|
||||||
shares: sidebarGetAlbumShares_album_shares[]
|
shares: sidebarGetAlbumShares_album_shares[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetAlbumShares {
|
export interface sidebarGetAlbumShares {
|
||||||
|
@ -28,9 +28,9 @@ export interface sidebarGetAlbumShares {
|
||||||
* Get album by id, user must own the album or be admin
|
* Get album by id, user must own the album or be admin
|
||||||
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
* If valid tokenCredentials are provided, the album may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
album: sidebarGetAlbumShares_album
|
album: sidebarGetAlbumShares_album;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetAlbumSharesVariables {
|
export interface sidebarGetAlbumSharesVariables {
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarGetPhotoShares_media_shares {
|
export interface sidebarGetPhotoShares_media_shares {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
id: string
|
id: string;
|
||||||
token: string
|
token: string;
|
||||||
/**
|
/**
|
||||||
* Whether or not a password is needed to access the share
|
* Whether or not a password is needed to access the share
|
||||||
*/
|
*/
|
||||||
hasPassword: boolean
|
hasPassword: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetPhotoShares_media {
|
export interface sidebarGetPhotoShares_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
shares: sidebarGetPhotoShares_media_shares[]
|
shares: sidebarGetPhotoShares_media_shares[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetPhotoShares {
|
export interface sidebarGetPhotoShares {
|
||||||
|
@ -28,9 +28,9 @@ export interface sidebarGetPhotoShares {
|
||||||
* Get media by id, user must own the media or be admin.
|
* Get media by id, user must own the media or be admin.
|
||||||
* If valid tokenCredentials are provided, the media may be retrived without further authentication
|
* If valid tokenCredentials are provided, the media may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
media: sidebarGetPhotoShares_media
|
media: sidebarGetPhotoShares_media;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarGetPhotoSharesVariables {
|
export interface sidebarGetPhotoSharesVariables {
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,155 +3,155 @@
|
||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MediaType } from './../../../__generated__/globalTypes'
|
import { MediaType } from "./../../../__generated__/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: sidebarPhoto
|
// GraphQL query operation: sidebarPhoto
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarPhoto_media_highRes {
|
export interface sidebarPhoto_media_highRes {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_thumbnail {
|
export interface sidebarPhoto_media_thumbnail {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_videoWeb {
|
export interface sidebarPhoto_media_videoWeb {
|
||||||
__typename: 'MediaURL'
|
__typename: "MediaURL";
|
||||||
/**
|
/**
|
||||||
* URL for previewing the image
|
* URL for previewing the image
|
||||||
*/
|
*/
|
||||||
url: string
|
url: string;
|
||||||
/**
|
/**
|
||||||
* Width of the image in pixels
|
* Width of the image in pixels
|
||||||
*/
|
*/
|
||||||
width: number
|
width: number;
|
||||||
/**
|
/**
|
||||||
* Height of the image in pixels
|
* Height of the image in pixels
|
||||||
*/
|
*/
|
||||||
height: number
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_videoMetadata {
|
export interface sidebarPhoto_media_videoMetadata {
|
||||||
__typename: 'VideoMetadata'
|
__typename: "VideoMetadata";
|
||||||
id: string
|
id: string;
|
||||||
width: number
|
width: number;
|
||||||
height: number
|
height: number;
|
||||||
duration: number
|
duration: number;
|
||||||
codec: string | null
|
codec: string | null;
|
||||||
framerate: number | null
|
framerate: number | null;
|
||||||
bitrate: string | null
|
bitrate: string | null;
|
||||||
colorProfile: string | null
|
colorProfile: string | null;
|
||||||
audio: string | null
|
audio: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_exif {
|
export interface sidebarPhoto_media_exif {
|
||||||
__typename: 'MediaEXIF'
|
__typename: "MediaEXIF";
|
||||||
id: string
|
id: string;
|
||||||
/**
|
/**
|
||||||
* The model name of the camera
|
* The model name of the camera
|
||||||
*/
|
*/
|
||||||
camera: string | null
|
camera: string | null;
|
||||||
/**
|
/**
|
||||||
* The maker of the camera
|
* The maker of the camera
|
||||||
*/
|
*/
|
||||||
maker: string | null
|
maker: string | null;
|
||||||
/**
|
/**
|
||||||
* The name of the lens
|
* The name of the lens
|
||||||
*/
|
*/
|
||||||
lens: string | null
|
lens: string | null;
|
||||||
dateShot: any | null
|
dateShot: any | null;
|
||||||
/**
|
/**
|
||||||
* The exposure time of the image
|
* The exposure time of the image
|
||||||
*/
|
*/
|
||||||
exposure: number | null
|
exposure: number | null;
|
||||||
/**
|
/**
|
||||||
* The aperature stops of the image
|
* The aperature stops of the image
|
||||||
*/
|
*/
|
||||||
aperture: number | null
|
aperture: number | null;
|
||||||
/**
|
/**
|
||||||
* The ISO setting of the image
|
* The ISO setting of the image
|
||||||
*/
|
*/
|
||||||
iso: number | null
|
iso: number | null;
|
||||||
/**
|
/**
|
||||||
* The focal length of the lens, when the image was taken
|
* The focal length of the lens, when the image was taken
|
||||||
*/
|
*/
|
||||||
focalLength: number | null
|
focalLength: number | null;
|
||||||
/**
|
/**
|
||||||
* A formatted description of the flash settings, when the image was taken
|
* A formatted description of the flash settings, when the image was taken
|
||||||
*/
|
*/
|
||||||
flash: number | null
|
flash: number | null;
|
||||||
/**
|
/**
|
||||||
* An index describing the mode for adjusting the exposure of the image
|
* An index describing the mode for adjusting the exposure of the image
|
||||||
*/
|
*/
|
||||||
exposureProgram: number | null
|
exposureProgram: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_faces_rectangle {
|
export interface sidebarPhoto_media_faces_rectangle {
|
||||||
__typename: 'FaceRectangle'
|
__typename: "FaceRectangle";
|
||||||
minX: number
|
minX: number;
|
||||||
maxX: number
|
maxX: number;
|
||||||
minY: number
|
minY: number;
|
||||||
maxY: number
|
maxY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_faces_faceGroup {
|
export interface sidebarPhoto_media_faces_faceGroup {
|
||||||
__typename: 'FaceGroup'
|
__typename: "FaceGroup";
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media_faces {
|
export interface sidebarPhoto_media_faces {
|
||||||
__typename: 'ImageFace'
|
__typename: "ImageFace";
|
||||||
id: string
|
id: string;
|
||||||
rectangle: sidebarPhoto_media_faces_rectangle
|
rectangle: sidebarPhoto_media_faces_rectangle;
|
||||||
faceGroup: sidebarPhoto_media_faces_faceGroup
|
faceGroup: sidebarPhoto_media_faces_faceGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto_media {
|
export interface sidebarPhoto_media {
|
||||||
__typename: 'Media'
|
__typename: "Media";
|
||||||
id: string
|
id: string;
|
||||||
title: string
|
title: string;
|
||||||
type: MediaType
|
type: MediaType;
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: sidebarPhoto_media_highRes | null
|
highRes: sidebarPhoto_media_highRes | null;
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: sidebarPhoto_media_thumbnail | null
|
thumbnail: sidebarPhoto_media_thumbnail | null;
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: sidebarPhoto_media_videoWeb | null
|
videoWeb: sidebarPhoto_media_videoWeb | null;
|
||||||
videoMetadata: sidebarPhoto_media_videoMetadata | null
|
videoMetadata: sidebarPhoto_media_videoMetadata | null;
|
||||||
exif: sidebarPhoto_media_exif | null
|
exif: sidebarPhoto_media_exif | null;
|
||||||
faces: sidebarPhoto_media_faces[]
|
faces: sidebarPhoto_media_faces[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhoto {
|
export interface sidebarPhoto {
|
||||||
|
@ -159,9 +159,9 @@ export interface sidebarPhoto {
|
||||||
* Get media by id, user must own the media or be admin.
|
* Get media by id, user must own the media or be admin.
|
||||||
* If valid tokenCredentials are provided, the media may be retrived without further authentication
|
* If valid tokenCredentials are provided, the media may be retrived without further authentication
|
||||||
*/
|
*/
|
||||||
media: sidebarPhoto_media
|
media: sidebarPhoto_media;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhotoVariables {
|
export interface sidebarPhotoVariables {
|
||||||
id: string
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarPhotoAddShare_shareMedia {
|
export interface sidebarPhotoAddShare_shareMedia {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
token: string
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhotoAddShare {
|
export interface sidebarPhotoAddShare {
|
||||||
/**
|
/**
|
||||||
* Generate share token for media
|
* Generate share token for media
|
||||||
*/
|
*/
|
||||||
shareMedia: sidebarPhotoAddShare_shareMedia
|
shareMedia: sidebarPhotoAddShare_shareMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarPhotoAddShareVariables {
|
export interface sidebarPhotoAddShareVariables {
|
||||||
id: string
|
id: string;
|
||||||
password?: string | null
|
password?: string | null;
|
||||||
expire?: any | null
|
expire?: any | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,22 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebarProtectShare_protectShareToken {
|
export interface sidebarProtectShare_protectShareToken {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
token: string
|
token: string;
|
||||||
/**
|
/**
|
||||||
* Whether or not a password is needed to access the share
|
* Whether or not a password is needed to access the share
|
||||||
*/
|
*/
|
||||||
hasPassword: boolean
|
hasPassword: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarProtectShare {
|
export interface sidebarProtectShare {
|
||||||
/**
|
/**
|
||||||
* Set a password for a token, if null is passed for the password argument, the password will be cleared
|
* Set a password for a token, if null is passed for the password argument, the password will be cleared
|
||||||
*/
|
*/
|
||||||
protectShareToken: sidebarProtectShare_protectShareToken
|
protectShareToken: sidebarProtectShare_protectShareToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebarProtectShareVariables {
|
export interface sidebarProtectShareVariables {
|
||||||
token: string
|
token: string;
|
||||||
password?: string | null
|
password?: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface sidebareDeleteShare_deleteShareToken {
|
export interface sidebareDeleteShare_deleteShareToken {
|
||||||
__typename: 'ShareToken'
|
__typename: "ShareToken";
|
||||||
token: string
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebareDeleteShare {
|
export interface sidebareDeleteShare {
|
||||||
/**
|
/**
|
||||||
* Delete a share token by it's token value
|
* Delete a share token by it's token value
|
||||||
*/
|
*/
|
||||||
deleteShareToken: sidebareDeleteShare_deleteShareToken
|
deleteShareToken: sidebareDeleteShare_deleteShareToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface sidebareDeleteShareVariables {
|
export interface sidebareDeleteShareVariables {
|
||||||
token: string
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { useQuery } from '@apollo/client'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Dropdown, { DropdownItem } from '../../primitives/form/Dropdown'
|
||||||
|
import { FavoriteCheckboxProps, FavoritesCheckbox } from '../album/AlbumFilter'
|
||||||
|
|
||||||
|
import { ReactComponent as DateIcon } from './icons/date.svg'
|
||||||
|
import { earliestMedia } from './__generated__/earliestMedia'
|
||||||
|
|
||||||
|
const EARLIEST_MEDIA_QUERY = gql`
|
||||||
|
query earliestMedia {
|
||||||
|
myMedia(
|
||||||
|
order: { order_by: "date_shot", order_direction: ASC }
|
||||||
|
paginate: { limit: 1 }
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
type DateSelectorProps = {
|
||||||
|
filterDate: string | null
|
||||||
|
setFilterDate(date: string | null): void
|
||||||
|
}
|
||||||
|
|
||||||
|
const DateSelector = ({ filterDate, setFilterDate }: DateSelectorProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const { data, loading } = useQuery<earliestMedia>(EARLIEST_MEDIA_QUERY)
|
||||||
|
|
||||||
|
let items: DropdownItem[] = [
|
||||||
|
{
|
||||||
|
value: 'all',
|
||||||
|
label: t('timeline_filter.date.dropdown_all', 'From today'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const dateStr = data.myMedia[0].date
|
||||||
|
const date = new Date(dateStr)
|
||||||
|
const now = new Date()
|
||||||
|
|
||||||
|
const currentYear = now.getFullYear()
|
||||||
|
const earliestYear = date.getFullYear()
|
||||||
|
|
||||||
|
const years: number[] = []
|
||||||
|
for (let i = currentYear - 1; i >= earliestYear; i--) {
|
||||||
|
years.push(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
const yearItems = years.map<DropdownItem>(x => ({
|
||||||
|
value: `${x}`,
|
||||||
|
label: `${x} and earlier`,
|
||||||
|
}))
|
||||||
|
items = [...items, ...yearItems]
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<fieldset>
|
||||||
|
<legend id="filter_group_date-label" className="inline-block mb-1">
|
||||||
|
<DateIcon
|
||||||
|
className="inline-block align-baseline mr-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<span>{t('timeline_filter.date.label', 'Date')}</span>
|
||||||
|
</legend>
|
||||||
|
<div>
|
||||||
|
<Dropdown
|
||||||
|
aria-labelledby="filter_group_date-label"
|
||||||
|
setSelected={date =>
|
||||||
|
date == 'all' ? setFilterDate(null) : setFilterDate(date)
|
||||||
|
}
|
||||||
|
value={filterDate || 'all'}
|
||||||
|
items={items}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimelineFiltersProps = DateSelectorProps & FavoriteCheckboxProps
|
||||||
|
|
||||||
|
const TimelineFilters = ({
|
||||||
|
onlyFavorites,
|
||||||
|
setOnlyFavorites,
|
||||||
|
filterDate,
|
||||||
|
setFilterDate,
|
||||||
|
}: TimelineFiltersProps) => {
|
||||||
|
return (
|
||||||
|
<div className="flex items-end gap-4 flex-wrap mb-4">
|
||||||
|
<DateSelector filterDate={filterDate} setFilterDate={setFilterDate} />
|
||||||
|
<FavoritesCheckbox
|
||||||
|
onlyFavorites={onlyFavorites}
|
||||||
|
setOnlyFavorites={setOnlyFavorites}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TimelineFilters
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { MockedProvider } from '@apollo/client/testing'
|
||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import React from 'react'
|
||||||
|
import { MemoryRouter } from 'react-router-dom'
|
||||||
|
import TimelineGallery, { MY_TIMELINE_QUERY } from './TimelineGallery'
|
||||||
|
import { timelineData } from './timelineTestData'
|
||||||
|
|
||||||
|
jest.mock('../../hooks/useScrollPagination')
|
||||||
|
|
||||||
|
test('timeline with media', async () => {
|
||||||
|
const graphqlMocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: MY_TIMELINE_QUERY,
|
||||||
|
variables: { onlyFavorites: false, offset: 0, limit: 200 },
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
data: {
|
||||||
|
myTimeline: timelineData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
render(
|
||||||
|
<MemoryRouter initialEntries={['/timeline']}>
|
||||||
|
<MockedProvider mocks={graphqlMocks}>
|
||||||
|
<TimelineGallery />
|
||||||
|
</MockedProvider>
|
||||||
|
</MemoryRouter>
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(screen.queryByLabelText('Show only favorites')).toBeInTheDocument()
|
||||||
|
|
||||||
|
expect(await screen.findAllByRole('link')).toHaveLength(4)
|
||||||
|
expect(await screen.findAllByRole('img')).toHaveLength(5)
|
||||||
|
|
||||||
|
screen.debug()
|
||||||
|
})
|
|
@ -4,7 +4,6 @@ import { useQuery, gql } from '@apollo/client'
|
||||||
import TimelineGroupDate from './TimelineGroupDate'
|
import TimelineGroupDate from './TimelineGroupDate'
|
||||||
import PresentView from '../photoGallery/presentView/PresentView'
|
import PresentView from '../photoGallery/presentView/PresentView'
|
||||||
import useURLParameters from '../../hooks/useURLParameters'
|
import useURLParameters from '../../hooks/useURLParameters'
|
||||||
import { FavoritesCheckbox } from '../album/AlbumFilter'
|
|
||||||
import useScrollPagination from '../../hooks/useScrollPagination'
|
import useScrollPagination from '../../hooks/useScrollPagination'
|
||||||
import PaginateLoader from '../PaginateLoader'
|
import PaginateLoader from '../PaginateLoader'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
@ -20,37 +19,42 @@ import {
|
||||||
import MediaSidebar from '../sidebar/MediaSidebar'
|
import MediaSidebar from '../sidebar/MediaSidebar'
|
||||||
import { SidebarContext } from '../sidebar/Sidebar'
|
import { SidebarContext } from '../sidebar/Sidebar'
|
||||||
import { urlPresentModeSetupHook } from '../photoGallery/photoGalleryReducer'
|
import { urlPresentModeSetupHook } from '../photoGallery/photoGalleryReducer'
|
||||||
|
import TimelineFilters from './TimelineFilters'
|
||||||
|
import client from '../../apolloClient'
|
||||||
|
|
||||||
const MY_TIMELINE_QUERY = gql`
|
export const MY_TIMELINE_QUERY = gql`
|
||||||
query myTimeline($onlyFavorites: Boolean, $limit: Int, $offset: Int) {
|
query myTimeline(
|
||||||
|
$onlyFavorites: Boolean
|
||||||
|
$limit: Int
|
||||||
|
$offset: Int
|
||||||
|
$fromDate: Time
|
||||||
|
) {
|
||||||
myTimeline(
|
myTimeline(
|
||||||
onlyFavorites: $onlyFavorites
|
onlyFavorites: $onlyFavorites
|
||||||
|
fromDate: $fromDate
|
||||||
paginate: { limit: $limit, offset: $offset }
|
paginate: { limit: $limit, offset: $offset }
|
||||||
) {
|
) {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
type
|
||||||
|
thumbnail {
|
||||||
|
url
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
highRes {
|
||||||
|
url
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
videoWeb {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
favorite
|
||||||
album {
|
album {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
media {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
type
|
|
||||||
thumbnail {
|
|
||||||
url
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
highRes {
|
|
||||||
url
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
videoWeb {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
favorite
|
|
||||||
}
|
|
||||||
mediaTotal
|
|
||||||
date
|
date
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +67,13 @@ export type TimelineActiveIndex = {
|
||||||
|
|
||||||
export type TimelineGroup = {
|
export type TimelineGroup = {
|
||||||
date: string
|
date: string
|
||||||
groups: myTimeline_myTimeline[]
|
albums: TimelineGroupAlbum[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TimelineGroupAlbum = {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
media: myTimeline_myTimeline[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineGallery = () => {
|
const TimelineGallery = () => {
|
||||||
|
@ -74,7 +84,10 @@ const TimelineGallery = () => {
|
||||||
|
|
||||||
const onlyFavorites = getParam('favorites') == '1' ? true : false
|
const onlyFavorites = getParam('favorites') == '1' ? true : false
|
||||||
const setOnlyFavorites = (favorites: boolean) =>
|
const setOnlyFavorites = (favorites: boolean) =>
|
||||||
setParam('favorites', favorites ? '1' : '0')
|
setParam('favorites', favorites ? '1' : null)
|
||||||
|
|
||||||
|
const filterDate = getParam('date')
|
||||||
|
const setFilterDate = (x: string) => setParam('date', x)
|
||||||
|
|
||||||
const favoritesNeedsRefresh = useRef(false)
|
const favoritesNeedsRefresh = useRef(false)
|
||||||
|
|
||||||
|
@ -94,8 +107,11 @@ const TimelineGallery = () => {
|
||||||
>(MY_TIMELINE_QUERY, {
|
>(MY_TIMELINE_QUERY, {
|
||||||
variables: {
|
variables: {
|
||||||
onlyFavorites,
|
onlyFavorites,
|
||||||
|
fromDate: filterDate
|
||||||
|
? `${parseInt(filterDate) + 1}-01-01T00:00:00Z`
|
||||||
|
: undefined,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 50,
|
limit: 200,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -123,6 +139,20 @@ const TimelineGallery = () => {
|
||||||
}
|
}
|
||||||
}, [mediaState.activeIndex])
|
}, [mediaState.activeIndex])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
;(async () => {
|
||||||
|
await client.resetStore()
|
||||||
|
await refetch({
|
||||||
|
onlyFavorites,
|
||||||
|
fromDate: filterDate
|
||||||
|
? `${parseInt(filterDate) + 1}-01-01T00:00:00Z`
|
||||||
|
: undefined,
|
||||||
|
offset: 0,
|
||||||
|
limit: 200,
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
}, [filterDate])
|
||||||
|
|
||||||
urlPresentModeSetupHook({
|
urlPresentModeSetupHook({
|
||||||
dispatchMedia,
|
dispatchMedia,
|
||||||
openPresentMode: event => {
|
openPresentMode: event => {
|
||||||
|
@ -155,12 +185,12 @@ const TimelineGallery = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-x-hidden">
|
<div className="overflow-x-hidden">
|
||||||
<div className="mb-2">
|
<TimelineFilters
|
||||||
<FavoritesCheckbox
|
onlyFavorites={onlyFavorites}
|
||||||
onlyFavorites={onlyFavorites}
|
setOnlyFavorites={setOnlyFavorites}
|
||||||
setOnlyFavorites={setOnlyFavorites}
|
filterDate={filterDate}
|
||||||
/>
|
setFilterDate={setFilterDate}
|
||||||
</div>
|
/>
|
||||||
<div className="-mx-3 flex flex-wrap" ref={containerElem}>
|
<div className="-mx-3 flex flex-wrap" ref={containerElem}>
|
||||||
{timelineGroups}
|
{timelineGroups}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
|
||||||
import { MediaThumbnail } from '../photoGallery/MediaThumbnail'
|
import { MediaThumbnail } from '../photoGallery/MediaThumbnail'
|
||||||
|
import { PhotoFiller } from '../photoGallery/PhotoGallery'
|
||||||
import {
|
import {
|
||||||
toggleFavoriteAction,
|
toggleFavoriteAction,
|
||||||
useMarkFavoriteMutation,
|
useMarkFavoriteMutation,
|
||||||
|
@ -13,20 +13,6 @@ import {
|
||||||
TimelineGalleryState,
|
TimelineGalleryState,
|
||||||
} from './timelineGalleryReducer'
|
} from './timelineGalleryReducer'
|
||||||
|
|
||||||
const TotalItemsBubble = styled(Link)`
|
|
||||||
position: absolute;
|
|
||||||
top: 24px;
|
|
||||||
right: 6px;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 8px 0;
|
|
||||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3);
|
|
||||||
color: black;
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
text-align: center;
|
|
||||||
`
|
|
||||||
|
|
||||||
type TimelineGroupAlbumProps = {
|
type TimelineGroupAlbumProps = {
|
||||||
dateIndex: number
|
dateIndex: number
|
||||||
albumIndex: number
|
albumIndex: number
|
||||||
|
@ -40,8 +26,11 @@ const TimelineGroupAlbum = ({
|
||||||
mediaState,
|
mediaState,
|
||||||
dispatchMedia,
|
dispatchMedia,
|
||||||
}: TimelineGroupAlbumProps) => {
|
}: TimelineGroupAlbumProps) => {
|
||||||
const { media, mediaTotal, album } =
|
const {
|
||||||
mediaState.timelineGroups[dateIndex].groups[albumIndex]
|
media,
|
||||||
|
title: albumTitle,
|
||||||
|
id: albumID,
|
||||||
|
} = mediaState.timelineGroups[dateIndex].albums[albumIndex]
|
||||||
|
|
||||||
const [markFavorite] = useMarkFavoriteMutation()
|
const [markFavorite] = useMarkFavoriteMutation()
|
||||||
|
|
||||||
|
@ -79,24 +68,14 @@ const TimelineGroupAlbum = ({
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
|
||||||
let itemsBubble = null
|
|
||||||
const mediaVisibleCount = media.length
|
|
||||||
if (mediaTotal > mediaVisibleCount) {
|
|
||||||
itemsBubble = (
|
|
||||||
<TotalItemsBubble to={`/album/${album.id}`}>
|
|
||||||
{`+${Math.min(mediaTotal - mediaVisibleCount, 99)}`}
|
|
||||||
</TotalItemsBubble>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-2">
|
<div className="mx-2">
|
||||||
<Link to={`/album/${album.id}`} className="hover:underline">
|
<Link to={`/album/${albumID}`} className="hover:underline">
|
||||||
{album.title}
|
{albumTitle}
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex flex-wrap items-center h-[210px] relative -mx-1 pr-4 overflow-hidden">
|
<div className="flex flex-wrap items-center relative -mx-1 overflow-hidden">
|
||||||
{mediaElms}
|
{mediaElms}
|
||||||
{itemsBubble}
|
<PhotoFiller />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,9 +27,9 @@ const TimelineGroupDate = ({
|
||||||
|
|
||||||
const group = mediaState.timelineGroups[groupIndex]
|
const group = mediaState.timelineGroups[groupIndex]
|
||||||
|
|
||||||
const albumGroupElms = group.groups.map((group, i) => (
|
const albumGroupElms = group.albums.map((album, i) => (
|
||||||
<TimelineGroupAlbum
|
<TimelineGroupAlbum
|
||||||
key={`${group.date}_${group.album.id}`}
|
key={`${group.date}_${album.id}`}
|
||||||
dateIndex={groupIndex}
|
dateIndex={groupIndex}
|
||||||
albumIndex={i}
|
albumIndex={i}
|
||||||
mediaState={mediaState}
|
mediaState={mediaState}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: earliestMedia
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface earliestMedia_myMedia {
|
||||||
|
__typename: 'Media'
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* The date the image was shot or the date it was imported as a fallback
|
||||||
|
*/
|
||||||
|
date: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface earliestMedia {
|
||||||
|
/**
|
||||||
|
* List of media owned by the logged in user
|
||||||
|
*/
|
||||||
|
myMedia: earliestMedia_myMedia[]
|
||||||
|
}
|
|
@ -9,53 +9,53 @@ import { MediaType } from './../../../__generated__/globalTypes'
|
||||||
// GraphQL query operation: myTimeline
|
// GraphQL query operation: myTimeline
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface myTimeline_myTimeline_thumbnail {
|
||||||
|
__typename: 'MediaURL'
|
||||||
|
/**
|
||||||
|
* URL for previewing the image
|
||||||
|
*/
|
||||||
|
url: string
|
||||||
|
/**
|
||||||
|
* Width of the image in pixels
|
||||||
|
*/
|
||||||
|
width: number
|
||||||
|
/**
|
||||||
|
* Height of the image in pixels
|
||||||
|
*/
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface myTimeline_myTimeline_highRes {
|
||||||
|
__typename: 'MediaURL'
|
||||||
|
/**
|
||||||
|
* URL for previewing the image
|
||||||
|
*/
|
||||||
|
url: string
|
||||||
|
/**
|
||||||
|
* Width of the image in pixels
|
||||||
|
*/
|
||||||
|
width: number
|
||||||
|
/**
|
||||||
|
* Height of the image in pixels
|
||||||
|
*/
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface myTimeline_myTimeline_videoWeb {
|
||||||
|
__typename: 'MediaURL'
|
||||||
|
/**
|
||||||
|
* URL for previewing the image
|
||||||
|
*/
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface myTimeline_myTimeline_album {
|
export interface myTimeline_myTimeline_album {
|
||||||
__typename: 'Album'
|
__typename: 'Album'
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myTimeline_myTimeline_media_thumbnail {
|
export interface myTimeline_myTimeline {
|
||||||
__typename: 'MediaURL'
|
|
||||||
/**
|
|
||||||
* URL for previewing the image
|
|
||||||
*/
|
|
||||||
url: string
|
|
||||||
/**
|
|
||||||
* Width of the image in pixels
|
|
||||||
*/
|
|
||||||
width: number
|
|
||||||
/**
|
|
||||||
* Height of the image in pixels
|
|
||||||
*/
|
|
||||||
height: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface myTimeline_myTimeline_media_highRes {
|
|
||||||
__typename: 'MediaURL'
|
|
||||||
/**
|
|
||||||
* URL for previewing the image
|
|
||||||
*/
|
|
||||||
url: string
|
|
||||||
/**
|
|
||||||
* Width of the image in pixels
|
|
||||||
*/
|
|
||||||
width: number
|
|
||||||
/**
|
|
||||||
* Height of the image in pixels
|
|
||||||
*/
|
|
||||||
height: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface myTimeline_myTimeline_media_videoWeb {
|
|
||||||
__typename: 'MediaURL'
|
|
||||||
/**
|
|
||||||
* URL for previewing the image
|
|
||||||
*/
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface myTimeline_myTimeline_media {
|
|
||||||
__typename: 'Media'
|
__typename: 'Media'
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
|
@ -63,27 +63,30 @@ export interface myTimeline_myTimeline_media {
|
||||||
/**
|
/**
|
||||||
* URL to display the media in a smaller resolution
|
* URL to display the media in a smaller resolution
|
||||||
*/
|
*/
|
||||||
thumbnail: myTimeline_myTimeline_media_thumbnail | null
|
thumbnail: myTimeline_myTimeline_thumbnail | null
|
||||||
/**
|
/**
|
||||||
* URL to display the photo in full resolution, will be null for videos
|
* URL to display the photo in full resolution, will be null for videos
|
||||||
*/
|
*/
|
||||||
highRes: myTimeline_myTimeline_media_highRes | null
|
highRes: myTimeline_myTimeline_highRes | null
|
||||||
/**
|
/**
|
||||||
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
* URL to get the video in a web format that can be played in the browser, will be null for photos
|
||||||
*/
|
*/
|
||||||
videoWeb: myTimeline_myTimeline_media_videoWeb | null
|
videoWeb: myTimeline_myTimeline_videoWeb | null
|
||||||
favorite: boolean
|
favorite: boolean
|
||||||
}
|
/**
|
||||||
|
* The album that holds the media
|
||||||
export interface myTimeline_myTimeline {
|
*/
|
||||||
__typename: 'TimelineGroup'
|
|
||||||
album: myTimeline_myTimeline_album
|
album: myTimeline_myTimeline_album
|
||||||
media: myTimeline_myTimeline_media[]
|
/**
|
||||||
mediaTotal: number
|
* The date the image was shot or the date it was imported as a fallback
|
||||||
|
*/
|
||||||
date: any
|
date: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface myTimeline {
|
export interface myTimeline {
|
||||||
|
/**
|
||||||
|
* Get a list of media, ordered first by day, then by album if multiple media was found for the same day.
|
||||||
|
*/
|
||||||
myTimeline: myTimeline_myTimeline[]
|
myTimeline: myTimeline_myTimeline[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,4 +94,5 @@ export interface myTimelineVariables {
|
||||||
onlyFavorites?: boolean | null
|
onlyFavorites?: boolean | null
|
||||||
limit?: number | null
|
limit?: number | null
|
||||||
offset?: number | null
|
offset?: number | null
|
||||||
|
fromDate?: any | null
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="13px" height="15px" viewBox="0 0 13 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M9.16666667,5.68434189e-14 C9.41979718,5.68434189e-14 9.62899397,0.188102588 9.66210226,0.432152962 L9.66666667,0.5 L9.666,1.333 L11.1666667,1.33333333 C12.1285626,1.33333333 12.9174396,2.07411552 12.9939226,3.01630483 L13,3.16666667 L13,12.5 C13,13.512522 12.1791887,14.3333333 11.1666667,14.3333333 L11.1666667,14.3333333 L1.83333333,14.3333333 C0.820811292,14.3333333 0,13.512522 0,12.5 L0,12.5 L0,3.16666667 C0,2.15414463 0.820811292,1.33333333 1.83333333,1.33333333 L1.83333333,1.33333333 L3.333,1.333 L3.33333333,0.5 C3.33333333,0.223857625 3.55719096,5.68434189e-14 3.83333333,5.68434189e-14 C4.08646384,5.68434189e-14 4.29566064,0.188102588 4.32876892,0.432152962 L4.33333333,0.5 L4.333,1.333 L8.666,1.333 L8.66666667,0.5 C8.66666667,0.223857625 8.89052429,5.68434189e-14 9.16666667,5.68434189e-14 Z M12,6.333 L1,6.333 L1,12.5 C1,12.9248344 1.31790432,13.2754183 1.72880177,13.3268405 L1.83333333,13.3333333 L11.1666667,13.3333333 C11.626904,13.3333333 12,12.9602373 12,12.5 L12,12.5 L12,6.333 Z M3.333,2.333 L1.83333333,2.33333333 C1.37309604,2.33333333 1,2.70642938 1,3.16666667 L1,3.16666667 L1,5.333 L12,5.333 L12,3.16666667 C12,2.74183224 11.6820957,2.39124835 11.2711982,2.33982618 L11.1666667,2.33333333 L9.666,2.333 L9.66666667,3.16666667 C9.66666667,3.44280904 9.44280904,3.66666667 9.16666667,3.66666667 C8.91353616,3.66666667 8.70433936,3.47856408 8.67123108,3.2345137 L8.66666667,3.16666667 L8.666,2.333 L4.333,2.333 L4.33333333,3.16666667 C4.33333333,3.44280904 4.10947571,3.66666667 3.83333333,3.66666667 C3.58020282,3.66666667 3.37100603,3.47856408 3.33789774,3.2345137 L3.33333333,3.16666667 L3.333,2.333 Z" fill="currentColor" fill-rule="nonzero"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -1,10 +1,10 @@
|
||||||
import { myTimeline_myTimeline } from './__generated__/myTimeline'
|
|
||||||
import { MediaType } from '../../__generated__/globalTypes'
|
import { MediaType } from '../../__generated__/globalTypes'
|
||||||
import {
|
import {
|
||||||
timelineGalleryReducer,
|
timelineGalleryReducer,
|
||||||
TimelineGalleryState,
|
TimelineGalleryState,
|
||||||
TimelineMediaIndex,
|
TimelineMediaIndex,
|
||||||
} from './timelineGalleryReducer'
|
} from './timelineGalleryReducer'
|
||||||
|
import { timelineData } from './timelineTestData'
|
||||||
|
|
||||||
describe('timeline gallery reducer', () => {
|
describe('timeline gallery reducer', () => {
|
||||||
const defaultEmptyState: TimelineGalleryState = {
|
const defaultEmptyState: TimelineGalleryState = {
|
||||||
|
@ -17,125 +17,6 @@ describe('timeline gallery reducer', () => {
|
||||||
timelineGroups: [],
|
timelineGroups: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
const timelineData: myTimeline_myTimeline[] = [
|
|
||||||
{
|
|
||||||
album: {
|
|
||||||
id: '5',
|
|
||||||
title: 'first album',
|
|
||||||
__typename: 'Album',
|
|
||||||
},
|
|
||||||
media: [
|
|
||||||
{
|
|
||||||
id: '165',
|
|
||||||
title: '3666760020.jpg',
|
|
||||||
type: MediaType.Photo,
|
|
||||||
thumbnail: {
|
|
||||||
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg',
|
|
||||||
width: 768,
|
|
||||||
height: 1024,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
highRes: {
|
|
||||||
url: 'http://localhost:4001/photo/3666760020_wijGDNZ2.jpg',
|
|
||||||
width: 3024,
|
|
||||||
height: 4032,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
videoWeb: null,
|
|
||||||
favorite: false,
|
|
||||||
__typename: 'Media',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '184',
|
|
||||||
title: '7414455077.jpg',
|
|
||||||
type: MediaType.Photo,
|
|
||||||
thumbnail: {
|
|
||||||
url: 'http://localhost:4001/photo/thumbnail_7414455077_jpg_9JYHHYh6.jpg',
|
|
||||||
width: 768,
|
|
||||||
height: 1024,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
highRes: {
|
|
||||||
url: 'http://localhost:4001/photo/7414455077_0ejDBiKr.jpg',
|
|
||||||
width: 3024,
|
|
||||||
height: 4032,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
videoWeb: null,
|
|
||||||
favorite: false,
|
|
||||||
__typename: 'Media',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
mediaTotal: 5,
|
|
||||||
date: '2019-09-21T00:00:00Z',
|
|
||||||
__typename: 'TimelineGroup',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
album: {
|
|
||||||
id: '5',
|
|
||||||
title: 'another album',
|
|
||||||
__typename: 'Album',
|
|
||||||
},
|
|
||||||
media: [
|
|
||||||
{
|
|
||||||
id: '165',
|
|
||||||
title: '3666760020.jpg',
|
|
||||||
type: MediaType.Photo,
|
|
||||||
thumbnail: {
|
|
||||||
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg',
|
|
||||||
width: 768,
|
|
||||||
height: 1024,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
highRes: {
|
|
||||||
url: 'http://localhost:4001/photo/3666760020_wijGDNZ2.jpg',
|
|
||||||
width: 3024,
|
|
||||||
height: 4032,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
videoWeb: null,
|
|
||||||
favorite: false,
|
|
||||||
__typename: 'Media',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
mediaTotal: 7,
|
|
||||||
date: '2019-09-21T00:00:00Z',
|
|
||||||
__typename: 'TimelineGroup',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'TimelineGroup',
|
|
||||||
album: {
|
|
||||||
__typename: 'Album',
|
|
||||||
id: '5',
|
|
||||||
title: 'album on another day',
|
|
||||||
},
|
|
||||||
date: '2019-09-13T00:00:00Z',
|
|
||||||
mediaTotal: 1,
|
|
||||||
media: [
|
|
||||||
{
|
|
||||||
__typename: 'Media',
|
|
||||||
favorite: false,
|
|
||||||
videoWeb: null,
|
|
||||||
thumbnail: {
|
|
||||||
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg',
|
|
||||||
width: 768,
|
|
||||||
height: 1024,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
highRes: {
|
|
||||||
url: 'http://localhost:4001/photo/3666760020_wijGDNZ2.jpg',
|
|
||||||
width: 3024,
|
|
||||||
height: 4032,
|
|
||||||
__typename: 'MediaURL',
|
|
||||||
},
|
|
||||||
id: '321',
|
|
||||||
title: 'asdfimg.jpg',
|
|
||||||
type: MediaType.Photo,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const defaultState = timelineGalleryReducer(defaultEmptyState, {
|
const defaultState = timelineGalleryReducer(defaultEmptyState, {
|
||||||
type: 'replaceTimelineGroups',
|
type: 'replaceTimelineGroups',
|
||||||
timeline: timelineData,
|
timeline: timelineData,
|
||||||
|
@ -151,68 +32,167 @@ describe('timeline gallery reducer', () => {
|
||||||
},
|
},
|
||||||
timelineGroups: [
|
timelineGroups: [
|
||||||
{
|
{
|
||||||
date: '2019-09-21T00:00:00Z',
|
date: '2020-12-13T00:00:00Z',
|
||||||
groups: [
|
albums: [
|
||||||
{
|
{
|
||||||
album: {
|
id: '522',
|
||||||
id: '5',
|
|
||||||
title: 'first album',
|
|
||||||
},
|
|
||||||
date: '2019-09-21T00:00:00Z',
|
|
||||||
media: [
|
media: [
|
||||||
{
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
album: {
|
||||||
|
__typename: 'Album',
|
||||||
|
id: '522',
|
||||||
|
title: 'random',
|
||||||
|
},
|
||||||
|
date: '2020-12-13T18:03:40Z',
|
||||||
favorite: false,
|
favorite: false,
|
||||||
highRes: {},
|
highRes: {
|
||||||
id: '165',
|
__typename: 'MediaURL',
|
||||||
thumbnail: {},
|
height: 4480,
|
||||||
title: '3666760020.jpg',
|
url: 'http://localhost:4001/photo/122A2876_5cSPMiKL.jpg',
|
||||||
type: 'Photo',
|
width: 6720,
|
||||||
},
|
},
|
||||||
{
|
id: '1058',
|
||||||
highRes: {},
|
thumbnail: {
|
||||||
id: '184',
|
__typename: 'MediaURL',
|
||||||
thumbnail: {},
|
height: 682,
|
||||||
title: '7414455077.jpg',
|
url: 'http://localhost:4001/photo/thumbnail_122A2876_jpg_Kp1U80vD.jpg',
|
||||||
|
width: 1024,
|
||||||
|
},
|
||||||
|
title: '122A2876.jpg',
|
||||||
type: 'Photo',
|
type: 'Photo',
|
||||||
|
videoWeb: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
mediaTotal: 5,
|
title: 'random',
|
||||||
},
|
|
||||||
{
|
|
||||||
album: {
|
|
||||||
id: '5',
|
|
||||||
title: 'another album',
|
|
||||||
},
|
|
||||||
date: '2019-09-21T00:00:00Z',
|
|
||||||
media: [
|
|
||||||
{
|
|
||||||
id: '165',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
mediaTotal: 7,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
date: '2019-09-13T00:00:00Z',
|
date: '2020-11-25T00:00:00Z',
|
||||||
groups: [
|
albums: [
|
||||||
{
|
{
|
||||||
album: {
|
id: '523',
|
||||||
id: '5',
|
title: 'another_album',
|
||||||
title: 'album on another day',
|
|
||||||
},
|
|
||||||
date: '2019-09-13T00:00:00Z',
|
|
||||||
media: [
|
media: [
|
||||||
{
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
album: {
|
||||||
|
__typename: 'Album',
|
||||||
|
id: '523',
|
||||||
|
title: 'another_album',
|
||||||
|
},
|
||||||
|
date: '2020-11-25T16:14:33Z',
|
||||||
favorite: false,
|
favorite: false,
|
||||||
highRes: {},
|
highRes: {
|
||||||
id: '321',
|
__typename: 'MediaURL',
|
||||||
thumbnail: {},
|
height: 4118,
|
||||||
title: 'asdfimg.jpg',
|
url: 'http://localhost:4001/photo/122A2630-Edit_ySQWFAgE.jpg',
|
||||||
|
width: 6177,
|
||||||
|
},
|
||||||
|
id: '1059',
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
height: 682,
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_pwjtMkpy.jpg',
|
||||||
|
width: 1024,
|
||||||
|
},
|
||||||
|
title: '122A2630-Edit.jpg',
|
||||||
type: 'Photo',
|
type: 'Photo',
|
||||||
|
videoWeb: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
album: {
|
||||||
|
__typename: 'Album',
|
||||||
|
id: '523',
|
||||||
|
title: 'another_album',
|
||||||
|
},
|
||||||
|
date: '2020-11-25T16:43:59Z',
|
||||||
|
favorite: false,
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
height: 884,
|
||||||
|
url: 'http://localhost:4001/photo/122A2785-2_mCnWjLdb.jpg',
|
||||||
|
width: 884,
|
||||||
|
},
|
||||||
|
id: '1060',
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
height: 1024,
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2785-2_jpg_CevmxEXf.jpg',
|
||||||
|
width: 1024,
|
||||||
|
},
|
||||||
|
title: '122A2785-2.jpg',
|
||||||
|
type: 'Photo',
|
||||||
|
videoWeb: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '522',
|
||||||
|
title: 'random',
|
||||||
|
media: [
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
album: {
|
||||||
|
__typename: 'Album',
|
||||||
|
id: '522',
|
||||||
|
title: 'random',
|
||||||
|
},
|
||||||
|
date: '2020-11-25T16:14:33Z',
|
||||||
|
favorite: false,
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
height: 4118,
|
||||||
|
url: 'http://localhost:4001/photo/122A2630-Edit_em9g89qg.jpg',
|
||||||
|
width: 6177,
|
||||||
|
},
|
||||||
|
id: '1056',
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
height: 682,
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_aJPCSDDl.jpg',
|
||||||
|
width: 1024,
|
||||||
|
},
|
||||||
|
title: '122A2630-Edit.jpg',
|
||||||
|
type: 'Photo',
|
||||||
|
videoWeb: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2020-11-09T00:00:00Z',
|
||||||
|
albums: [
|
||||||
|
{
|
||||||
|
id: '522',
|
||||||
|
title: 'random',
|
||||||
|
media: [
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1054',
|
||||||
|
title: '122A2559.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2559_jpg_MsOJtPi8.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 712,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2559_FDsQHuBN.jpg',
|
||||||
|
width: 6246,
|
||||||
|
height: 4346,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '522', title: 'random' },
|
||||||
|
date: '2020-11-09T15:38:09Z',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
mediaTotal: 1,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -267,20 +247,20 @@ describe('timeline gallery reducer', () => {
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 1,
|
media: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'next album',
|
name: 'next album',
|
||||||
in: {
|
in: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 1,
|
media: 1,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 1,
|
album: 1,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
|
@ -288,12 +268,12 @@ describe('timeline gallery reducer', () => {
|
||||||
{
|
{
|
||||||
name: 'next date',
|
name: 'next date',
|
||||||
in: {
|
in: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 1,
|
album: 1,
|
||||||
media: 1,
|
media: 0,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 1,
|
date: 2,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
|
@ -301,12 +281,12 @@ describe('timeline gallery reducer', () => {
|
||||||
{
|
{
|
||||||
name: 'reached end',
|
name: 'reached end',
|
||||||
in: {
|
in: {
|
||||||
date: 1,
|
date: 2,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 1,
|
date: 2,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
|
@ -366,12 +346,12 @@ describe('timeline gallery reducer', () => {
|
||||||
{
|
{
|
||||||
name: 'previous album',
|
name: 'previous album',
|
||||||
in: {
|
in: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 1,
|
album: 1,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 1,
|
media: 1,
|
||||||
},
|
},
|
||||||
|
@ -379,12 +359,12 @@ describe('timeline gallery reducer', () => {
|
||||||
{
|
{
|
||||||
name: 'previous date',
|
name: 'previous date',
|
||||||
in: {
|
in: {
|
||||||
date: 1,
|
date: 2,
|
||||||
album: 0,
|
album: 0,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
out: {
|
out: {
|
||||||
date: 0,
|
date: 1,
|
||||||
album: 1,
|
album: 1,
|
||||||
media: 0,
|
media: 0,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import { myTimeline_myTimeline } from './__generated__/myTimeline'
|
||||||
myTimeline_myTimeline,
|
import { TimelineGroup, TimelineGroupAlbum } from './TimelineGallery'
|
||||||
myTimeline_myTimeline_media,
|
|
||||||
} from './__generated__/myTimeline'
|
|
||||||
import { TimelineGroup } from './TimelineGallery'
|
|
||||||
import { GalleryAction } from '../photoGallery/photoGalleryReducer'
|
import { GalleryAction } from '../photoGallery/photoGalleryReducer'
|
||||||
|
import { isNil } from '../../helpers/utils'
|
||||||
|
|
||||||
export interface TimelineMediaIndex {
|
export interface TimelineMediaIndex {
|
||||||
date: number
|
date: number
|
||||||
|
@ -30,18 +28,7 @@ export function timelineGalleryReducer(
|
||||||
): TimelineGalleryState {
|
): TimelineGalleryState {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'replaceTimelineGroups': {
|
case 'replaceTimelineGroups': {
|
||||||
const dateGroupedAlbums = action.timeline.reduce((acc, val) => {
|
const timelineGroups = convertMediaToTimelineGroups(action.timeline)
|
||||||
if (acc.length == 0 || acc[acc.length - 1].date != val.date) {
|
|
||||||
acc.push({
|
|
||||||
date: val.date,
|
|
||||||
groups: [val],
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
acc[acc.length - 1].groups.push(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc
|
|
||||||
}, [] as TimelineGroup[])
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -50,7 +37,7 @@ export function timelineGalleryReducer(
|
||||||
date: -1,
|
date: -1,
|
||||||
media: -1,
|
media: -1,
|
||||||
},
|
},
|
||||||
timelineGroups: dateGroupedAlbums,
|
timelineGroups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 'nextImage': {
|
case 'nextImage': {
|
||||||
|
@ -64,7 +51,7 @@ export function timelineGalleryReducer(
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
const albumGroups = timelineGroups[activeIndex.date].groups
|
const albumGroups = timelineGroups[activeIndex.date].albums
|
||||||
const albumMedia = albumGroups[activeIndex.album].media
|
const albumMedia = albumGroups[activeIndex.album].media
|
||||||
|
|
||||||
if (activeIndex.media < albumMedia.length - 1) {
|
if (activeIndex.media < albumMedia.length - 1) {
|
||||||
|
@ -124,7 +111,7 @@ export function timelineGalleryReducer(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeIndex.album > 0) {
|
if (activeIndex.album > 0) {
|
||||||
const albumGroups = state.timelineGroups[activeIndex.date].groups
|
const albumGroups = state.timelineGroups[activeIndex.date].albums
|
||||||
const albumMedia = albumGroups[activeIndex.album - 1].media
|
const albumMedia = albumGroups[activeIndex.album - 1].media
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -138,7 +125,7 @@ export function timelineGalleryReducer(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeIndex.date > 0) {
|
if (activeIndex.date > 0) {
|
||||||
const albumGroups = state.timelineGroups[activeIndex.date - 1].groups
|
const albumGroups = state.timelineGroups[activeIndex.date - 1].albums
|
||||||
const albumMedia = albumGroups[albumGroups.length - 1].media
|
const albumMedia = albumGroups[albumGroups.length - 1].media
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -181,9 +168,9 @@ export const getTimelineImage = ({
|
||||||
}: {
|
}: {
|
||||||
mediaState: TimelineGalleryState
|
mediaState: TimelineGalleryState
|
||||||
index: TimelineMediaIndex
|
index: TimelineMediaIndex
|
||||||
}): myTimeline_myTimeline_media => {
|
}): myTimeline_myTimeline => {
|
||||||
const { date, album, media } = index
|
const { date, album, media } = index
|
||||||
return mediaState.timelineGroups[date].groups[album].media[media]
|
return mediaState.timelineGroups[date].albums[album].media[media]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getActiveTimelineImage = ({
|
export const getActiveTimelineImage = ({
|
||||||
|
@ -203,6 +190,74 @@ export const getActiveTimelineImage = ({
|
||||||
return getTimelineImage({ mediaState, index: mediaState.activeIndex })
|
return getTimelineImage({ mediaState, index: mediaState.activeIndex })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertMediaToTimelineGroups(
|
||||||
|
timelineMedia: myTimeline_myTimeline[]
|
||||||
|
): TimelineGroup[] {
|
||||||
|
const timelineGroups: TimelineGroup[] = []
|
||||||
|
let albums: TimelineGroupAlbum[] = []
|
||||||
|
let nextAlbum: TimelineGroupAlbum | null = null
|
||||||
|
|
||||||
|
const sameDay = (a: string, b: string) => {
|
||||||
|
return (
|
||||||
|
a.replace(/\d{2}:\d{2}:\d{2}/, '00:00:00') ==
|
||||||
|
b.replace(/\d{2}:\d{2}:\d{2}/, '00:00:00')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const media of timelineMedia) {
|
||||||
|
if (nextAlbum == null) {
|
||||||
|
nextAlbum = {
|
||||||
|
id: media.album.id,
|
||||||
|
title: media.album.title,
|
||||||
|
media: [media],
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// if date changes
|
||||||
|
if (!sameDay(nextAlbum.media[0].date, media.date)) {
|
||||||
|
albums.push(nextAlbum)
|
||||||
|
|
||||||
|
timelineGroups.push({
|
||||||
|
date: albums[0].media[0].date.replace(/\d{2}:\d{2}:\d{2}/, '00:00:00'),
|
||||||
|
albums: albums,
|
||||||
|
})
|
||||||
|
albums = []
|
||||||
|
nextAlbum = {
|
||||||
|
id: media.album.id,
|
||||||
|
title: media.album.title,
|
||||||
|
media: [media],
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// if album changes
|
||||||
|
if (nextAlbum.id != media.album.id) {
|
||||||
|
albums.push(nextAlbum)
|
||||||
|
nextAlbum = {
|
||||||
|
id: media.album.id,
|
||||||
|
title: media.album.title,
|
||||||
|
media: [media],
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// same album and date
|
||||||
|
nextAlbum.media.push(media)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNil(nextAlbum)) {
|
||||||
|
albums.push(nextAlbum)
|
||||||
|
|
||||||
|
timelineGroups.push({
|
||||||
|
date: albums[0].media[0].date.replace(/\d{2}:\d{2}:\d{2}/, '00:00:00'),
|
||||||
|
albums: albums,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return timelineGroups
|
||||||
|
}
|
||||||
|
|
||||||
export const openTimelinePresentMode = ({
|
export const openTimelinePresentMode = ({
|
||||||
dispatchMedia,
|
dispatchMedia,
|
||||||
activeIndex,
|
activeIndex,
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
import { MediaType } from '../../__generated__/globalTypes'
|
||||||
|
import { myTimeline_myTimeline } from './__generated__/myTimeline'
|
||||||
|
|
||||||
|
export const timelineData: myTimeline_myTimeline[] = [
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1058',
|
||||||
|
title: '122A2876.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2876_jpg_Kp1U80vD.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 682,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2876_5cSPMiKL.jpg',
|
||||||
|
width: 6720,
|
||||||
|
height: 4480,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '522', title: 'random' },
|
||||||
|
date: '2020-12-13T18:03:40Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1059',
|
||||||
|
title: '122A2630-Edit.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_pwjtMkpy.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 682,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2630-Edit_ySQWFAgE.jpg',
|
||||||
|
width: 6177,
|
||||||
|
height: 4118,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '523', title: 'another_album' },
|
||||||
|
date: '2020-11-25T16:14:33Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1060',
|
||||||
|
title: '122A2785-2.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2785-2_jpg_CevmxEXf.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 1024,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2785-2_mCnWjLdb.jpg',
|
||||||
|
width: 884,
|
||||||
|
height: 884,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '523', title: 'another_album' },
|
||||||
|
date: '2020-11-25T16:43:59Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1056',
|
||||||
|
title: '122A2630-Edit.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_aJPCSDDl.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 682,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2630-Edit_em9g89qg.jpg',
|
||||||
|
width: 6177,
|
||||||
|
height: 4118,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '522', title: 'random' },
|
||||||
|
date: '2020-11-25T16:14:33Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Media',
|
||||||
|
id: '1054',
|
||||||
|
title: '122A2559.jpg',
|
||||||
|
type: MediaType.Photo,
|
||||||
|
thumbnail: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/thumbnail_122A2559_jpg_MsOJtPi8.jpg',
|
||||||
|
width: 1024,
|
||||||
|
height: 712,
|
||||||
|
},
|
||||||
|
highRes: {
|
||||||
|
__typename: 'MediaURL',
|
||||||
|
url: 'http://localhost:4001/photo/122A2559_FDsQHuBN.jpg',
|
||||||
|
width: 6246,
|
||||||
|
height: 4346,
|
||||||
|
},
|
||||||
|
videoWeb: null,
|
||||||
|
favorite: false,
|
||||||
|
album: { __typename: 'Album', id: '522', title: 'random' },
|
||||||
|
date: '2020-11-09T15:38:09Z',
|
||||||
|
},
|
||||||
|
]
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Simpelt og Brugervenligt Photo-galleri for Personlige Servere"
|
"description": "Simpelt og Brugervenligt Photo-galleri for Personlige Servere"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Navn",
|
"label_placeholder": "Navn",
|
||||||
"unlabeled": "Ikke navngivet",
|
"unlabeled": "Ikke navngivet",
|
||||||
"unlabeled_person": "Ikke navngivet person"
|
"unlabeled_person": "Ikke navngivet person"
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": "Sammenflet"
|
"merge": "Sammenflet"
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": "Albumtitel"
|
"title_placeholder": "Albumtitel"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Kort",
|
"places": "Kort",
|
||||||
"settings": "Indstillinger"
|
"settings": "Indstillinger"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Loader album",
|
"loading_album": "Loader album",
|
||||||
"login": "Log ind",
|
"login": "Log ind",
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": "Søg billeder..."
|
"search_images_placeholder": "Søg billeder..."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
@ -53,6 +59,14 @@
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Offentlige delinger"
|
"table_header": "Offentlige delinger"
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"filesize": {
|
||||||
|
"giga_byte_plural": null,
|
||||||
|
"kilo_byte_plural": null,
|
||||||
|
"mega_byte_plural": null,
|
||||||
|
"tera_byte_plural": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Einfache und nutzerfreundliche Fotogallerie für Homeserver"
|
"description": "Einfache und nutzerfreundliche Fotogallerie für Homeserver"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Zuordnung",
|
"label_placeholder": "Zuordnung",
|
||||||
"unlabeled": "Nicht zugeordnet",
|
"unlabeled": "Nicht zugeordnet",
|
||||||
"unlabeled_person": null
|
"unlabeled_person": null
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": null
|
"merge": null
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Orte",
|
"places": "Orte",
|
||||||
"settings": "Einstellungen"
|
"settings": "Einstellungen"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Lade Album",
|
"loading_album": "Lade Album",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Fotos"
|
"photos": "Fotos",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,23 +70,55 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": null
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Administrator"
|
"admin": "Administrator",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "Album Optionen"
|
"title": "Album Optionen",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Öffentliche Freigabe"
|
"table_header": "Öffentliche Freigabe",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"filesize": {
|
||||||
|
"giga_byte_plural": null,
|
||||||
|
"kilo_byte_plural": null,
|
||||||
|
"mega_byte_plural": null,
|
||||||
|
"tera_byte_plural": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Simple and User-friendly Photo Gallery for Personal Servers"
|
"description": "Simple and User-friendly Photo Gallery for Personal Servers"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": "Change label",
|
||||||
|
"detach_face": "Detach face",
|
||||||
|
"merge_face": "Merge face",
|
||||||
|
"move_faces": "Move faces"
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Label",
|
"label_placeholder": "Label",
|
||||||
"unlabeled": "Unlabeled",
|
"unlabeled": "Unlabeled",
|
||||||
"unlabeled_person": "Unlabeled person"
|
"unlabeled_person": "Unlabeled person"
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": "Change label",
|
|
||||||
"merge_face": "Merge face",
|
|
||||||
"detach_face": "Detach face",
|
|
||||||
"move_faces": "Move faces"
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": "Merge"
|
"merge": "Merge"
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": "Album cover",
|
||||||
|
"cover_photo": "Album cover",
|
||||||
|
"reset_cover": "Reset cover photo",
|
||||||
|
"set_cover": "Set as album cover photo",
|
||||||
"title_placeholder": "Album title"
|
"title_placeholder": "Album title"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Places",
|
"places": "Places",
|
||||||
"settings": "Settings"
|
"settings": "Settings"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": "From today",
|
||||||
|
"label": "Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Loading album",
|
"loading_album": "Loading album",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Una galería de fotos sencilla y fácil de usar para servidores personales"
|
"description": "Una galería de fotos sencilla y fácil de usar para servidores personales"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Etiqueta",
|
"label_placeholder": "Etiqueta",
|
||||||
"unlabeled": "Sin etiquetar",
|
"unlabeled": "Sin etiquetar",
|
||||||
"unlabeled_person": null
|
"unlabeled_person": null
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": null
|
"merge": null
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Lugares",
|
"places": "Lugares",
|
||||||
"settings": "Opciones"
|
"settings": "Opciones"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Cargando álbum",
|
"loading_album": "Cargando álbum",
|
||||||
"login": null,
|
"login": null,
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Fotos"
|
"photos": "Fotos",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,13 +70,26 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": null
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Administrador"
|
"admin": "Administrador",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -87,13 +101,32 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "opciones de álbum"
|
"title": "opciones de álbum",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Compartidos públicos"
|
"table_header": "Compartidos públicos",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"filesize": {
|
||||||
|
"giga_byte_plural": null,
|
||||||
|
"kilo_byte_plural": null,
|
||||||
|
"mega_byte_plural": null,
|
||||||
|
"tera_byte_plural": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"login": null
|
"login": null
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Galerie Photo simple et convivial pour les Serveurs Personnels"
|
"description": "Galerie Photo simple et convivial pour les Serveurs Personnels"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": "Changer le label",
|
||||||
|
"detach_face": "Détacher le visage",
|
||||||
|
"merge_face": "Fusionner le visage",
|
||||||
|
"move_faces": "Déplacer les visages"
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Étiquette",
|
"label_placeholder": "Étiquette",
|
||||||
"unlabeled": "Sans étiquette",
|
"unlabeled": "Sans étiquette",
|
||||||
"unlabeled_person": "Personne sans étiquette"
|
"unlabeled_person": "Personne sans étiquette"
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": "Changer le label",
|
|
||||||
"merge_face": "Fusionner le visage",
|
|
||||||
"detach_face": "Détacher le visage",
|
|
||||||
"move_faces": "Déplacer les visages"
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": "Fusionner"
|
"merge": "Fusionner"
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": "Titre de l'Album"
|
"title_placeholder": "Titre de l'Album"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Lieux",
|
"places": "Lieux",
|
||||||
"settings": "Réglages"
|
"settings": "Réglages"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Chargement de l'album",
|
"loading_album": "Chargement de l'album",
|
||||||
"login": "Connexion",
|
"login": "Connexion",
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Galleria fotografica semplice e user-friendly per il tuo server"
|
"description": "Galleria fotografica semplice e user-friendly per il tuo server"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Etichetta",
|
"label_placeholder": "Etichetta",
|
||||||
"unlabeled": "Senza etichetta",
|
"unlabeled": "Senza etichetta",
|
||||||
"unlabeled_person": "Persona senza etichetta"
|
"unlabeled_person": "Persona senza etichetta"
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": "Unisci"
|
"merge": "Unisci"
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Luoghi",
|
"places": "Luoghi",
|
||||||
"settings": "Impostazioni"
|
"settings": "Impostazioni"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Caricamento album",
|
"loading_album": "Caricamento album",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Foto"
|
"photos": "Foto",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -36,23 +37,55 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": "Cerca immagini..."
|
"search_images_placeholder": "Cerca immagini..."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Admin"
|
"admin": "Admin",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "Opzioni Album"
|
"title": "Opzioni Album",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Condivisioni pubbliche"
|
"table_header": "Condivisioni pubbliche",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"filesize": {
|
||||||
|
"giga_byte_plural": null,
|
||||||
|
"kilo_byte_plural": null,
|
||||||
|
"mega_byte_plural": null,
|
||||||
|
"tera_byte_plural": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Prosta i przyjazna dla użytkownika galeria zdjęć"
|
"description": "Prosta i przyjazna dla użytkownika galeria zdjęć"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Etykieta",
|
"label_placeholder": "Etykieta",
|
||||||
"unlabeled": "Nieoznakowany",
|
"unlabeled": "Nieoznakowany",
|
||||||
"unlabeled_person": null
|
"unlabeled_person": null
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": null
|
"merge": null
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -300,6 +304,12 @@
|
||||||
"places": "Miejsca",
|
"places": "Miejsca",
|
||||||
"settings": "Ustawienia"
|
"settings": "Ustawienia"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Ładowanie albumu",
|
"loading_album": "Ładowanie albumu",
|
||||||
"login": null,
|
"login": null,
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Zdjęcia"
|
"photos": "Zdjęcia",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,13 +70,26 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": null
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Admin"
|
"admin": "Admin",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -87,7 +101,8 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "Opcje albumu"
|
"title": "Opcje albumu",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"filesize": {
|
"filesize": {
|
||||||
|
@ -99,14 +114,36 @@
|
||||||
"giga_byte": "{{count}} GB",
|
"giga_byte": "{{count}} GB",
|
||||||
"kilo_byte": "{{count}} KB",
|
"kilo_byte": "{{count}} KB",
|
||||||
"mega_byte": "{{count}} MB",
|
"mega_byte": "{{count}} MB",
|
||||||
"tera_byte": "{{count}} TB"
|
"tera_byte": "{{count}} TB",
|
||||||
|
"giga_byte_0": null,
|
||||||
|
"giga_byte_1": null,
|
||||||
|
"giga_byte_2": null,
|
||||||
|
"kilo_byte_0": null,
|
||||||
|
"kilo_byte_1": null,
|
||||||
|
"kilo_byte_2": null,
|
||||||
|
"mega_byte_0": null,
|
||||||
|
"mega_byte_1": null,
|
||||||
|
"mega_byte_2": null,
|
||||||
|
"tera_byte_0": null,
|
||||||
|
"tera_byte_1": null,
|
||||||
|
"tera_byte_2": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Publiczne udostępnienia"
|
"table_header": "Publiczne udostępnienia",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"login": null
|
"login": null
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Простая и Удобная Фото Галерея для Личного Сервера"
|
"description": "Простая и Удобная Фото Галерея для Личного Сервера"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Метка",
|
"label_placeholder": "Метка",
|
||||||
"unlabeled": "Без метки",
|
"unlabeled": "Без метки",
|
||||||
"unlabeled_person": "Человек без метки"
|
"unlabeled_person": "Человек без метки"
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": "Объединить"
|
"merge": "Объединить"
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -300,6 +304,12 @@
|
||||||
"places": "Места",
|
"places": "Места",
|
||||||
"settings": "Настройки"
|
"settings": "Настройки"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Загрузка альбома",
|
"loading_album": "Загрузка альбома",
|
||||||
"login": "Имя пользователя",
|
"login": "Имя пользователя",
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Фото"
|
"photos": "Фото",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -36,20 +37,34 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": "Поиск фото..."
|
"search_images_placeholder": "Поиск фото..."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Администрирование"
|
"admin": "Администрирование",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "Свойства альбома"
|
"title": "Свойства альбома",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"filesize": {
|
"filesize": {
|
||||||
|
@ -58,11 +73,36 @@
|
||||||
"giga_byte": "{{count}} ГБ",
|
"giga_byte": "{{count}} ГБ",
|
||||||
"kilo_byte": "{{count}} КБ",
|
"kilo_byte": "{{count}} КБ",
|
||||||
"mega_byte": "{{count}} МБ",
|
"mega_byte": "{{count}} МБ",
|
||||||
"tera_byte": "{{count}} ТБ"
|
"tera_byte": "{{count}} ТБ",
|
||||||
|
"byte_0": null,
|
||||||
|
"byte_1": null,
|
||||||
|
"byte_2": null,
|
||||||
|
"giga_byte_0": null,
|
||||||
|
"giga_byte_1": null,
|
||||||
|
"giga_byte_2": null,
|
||||||
|
"kilo_byte_0": null,
|
||||||
|
"kilo_byte_1": null,
|
||||||
|
"kilo_byte_2": null,
|
||||||
|
"mega_byte_0": null,
|
||||||
|
"mega_byte_1": null,
|
||||||
|
"mega_byte_2": null,
|
||||||
|
"tera_byte_0": null,
|
||||||
|
"tera_byte_1": null,
|
||||||
|
"tera_byte_2": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Общий доступ"
|
"table_header": "Общий доступ",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,17 @@
|
||||||
"description": "Enkelt och Användarvänligt fotogalleri för personliga servrar"
|
"description": "Enkelt och Användarvänligt fotogalleri för personliga servrar"
|
||||||
},
|
},
|
||||||
"people_page": {
|
"people_page": {
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
"face_group": {
|
"face_group": {
|
||||||
"label_placeholder": "Märkning",
|
"label_placeholder": "Märkning",
|
||||||
"unlabeled": "Omärkt",
|
"unlabeled": "Omärkt",
|
||||||
"unlabeled_person": null
|
"unlabeled_person": null
|
||||||
},
|
},
|
||||||
"action_label": {
|
|
||||||
"change_label": null,
|
|
||||||
"merge_face": null,
|
|
||||||
"detach_face": null,
|
|
||||||
"move_faces": null
|
|
||||||
},
|
|
||||||
"modal": {
|
"modal": {
|
||||||
"action": {
|
"action": {
|
||||||
"merge": null
|
"merge": null
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
|
"album_cover": null,
|
||||||
|
"cover_photo": null,
|
||||||
|
"reset_cover": null,
|
||||||
|
"set_cover": null,
|
||||||
"title_placeholder": null
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
|
@ -295,6 +299,12 @@
|
||||||
"places": "Platser",
|
"places": "Platser",
|
||||||
"settings": "Inställningar"
|
"settings": "Inställningar"
|
||||||
},
|
},
|
||||||
|
"timeline_filter": {
|
||||||
|
"date": {
|
||||||
|
"dropdown_all": null,
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"loading_album": "Laddar album",
|
"loading_album": "Laddar album",
|
||||||
"login": null,
|
"login": null,
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"header": {
|
"header": {
|
||||||
"search": {
|
"search": {
|
||||||
"result_type": {
|
"result_type": {
|
||||||
"photos": "Bilder"
|
"photos": "Bilder",
|
||||||
|
"media": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,6 +70,18 @@
|
||||||
"select_image_faces": {
|
"select_image_faces": {
|
||||||
"search_images_placeholder": null
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"action_label": {
|
||||||
|
"change_label": null,
|
||||||
|
"merge_face": null,
|
||||||
|
"detach_face": null,
|
||||||
|
"move_faces": null
|
||||||
|
},
|
||||||
|
"tableselect_face_group": {
|
||||||
|
"search_faces_placeholder": null
|
||||||
|
},
|
||||||
|
"tableselect_image_faces": {
|
||||||
|
"search_images_placeholder": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"places_page": {
|
"places_page": {
|
||||||
|
@ -78,7 +91,8 @@
|
||||||
"users": {
|
"users": {
|
||||||
"table": {
|
"table": {
|
||||||
"column_names": {
|
"column_names": {
|
||||||
"admin": "Admin"
|
"admin": "Admin",
|
||||||
|
"capabilities": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -90,13 +104,32 @@
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"album": {
|
"album": {
|
||||||
"title": "Albuminställningar"
|
"title": "Albuminställningar",
|
||||||
|
"title_placeholder": null
|
||||||
},
|
},
|
||||||
"sharing": {
|
"sharing": {
|
||||||
"table_header": "Publika delningar"
|
"table_header": "Publika delningar",
|
||||||
|
"delete": null,
|
||||||
|
"more": null
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"filesize": {
|
||||||
|
"giga_byte_plural": null,
|
||||||
|
"kilo_byte_plural": null,
|
||||||
|
"mega_byte_plural": null,
|
||||||
|
"tera_byte_plural": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"login": null
|
"login": null
|
||||||
|
},
|
||||||
|
"album_filter": {
|
||||||
|
"sort": null
|
||||||
|
},
|
||||||
|
"share_page": {
|
||||||
|
"protected_share": {
|
||||||
|
"password_required_error": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,10 @@ function useScrollPagination<D>({
|
||||||
reconfigureIntersectionObserver()
|
reconfigureIntersectionObserver()
|
||||||
}, [fetchMore, data, finished])
|
}, [fetchMore, data, finished])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFinished(false)
|
||||||
|
}, [data])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
containerElem,
|
containerElem,
|
||||||
finished,
|
finished,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
export type UrlKeyValuePair = { key: string; value: string }
|
export type UrlKeyValuePair = { key: string; value: string | null }
|
||||||
|
|
||||||
export type UrlParams = {
|
export type UrlParams = {
|
||||||
getParam(key: string, defaultValue?: string | null): string | null
|
getParam(key: string, defaultValue?: string | null): string | null
|
||||||
setParam(key: string, value: string): void
|
setParam(key: string, value: string | null): void
|
||||||
setParams(pairs: UrlKeyValuePair[]): void
|
setParams(pairs: UrlKeyValuePair[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,18 +19,30 @@ function useURLParameters(): UrlParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateParams = () => {
|
const updateParams = () => {
|
||||||
history.replaceState({}, '', url.pathname + '?' + params.toString())
|
if (params.toString()) {
|
||||||
|
history.replaceState({}, '', url.pathname + '?' + params.toString())
|
||||||
|
} else {
|
||||||
|
history.replaceState({}, '', url.pathname)
|
||||||
|
}
|
||||||
setUrlString(document.location.href)
|
setUrlString(document.location.href)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setParam = (key: string, value: string) => {
|
const setParam = (key: string, value: string | null) => {
|
||||||
params.set(key, value)
|
if (value) {
|
||||||
|
params.set(key, value)
|
||||||
|
} else {
|
||||||
|
params.delete(key)
|
||||||
|
}
|
||||||
updateParams()
|
updateParams()
|
||||||
}
|
}
|
||||||
|
|
||||||
const setParams = (pairs: UrlKeyValuePair[]) => {
|
const setParams = (pairs: UrlKeyValuePair[]) => {
|
||||||
for (const pair of pairs) {
|
for (const pair of pairs) {
|
||||||
params.set(pair.key, pair.value)
|
if (pair.value) {
|
||||||
|
params.set(pair.key, pair.value)
|
||||||
|
} else {
|
||||||
|
params.delete(pair.key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateParams()
|
updateParams()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue