WIP: Work on new timeline

This commit is contained in:
viktorstrate
2021-09-18 20:17:24 +02:00
parent bb613345ee
commit 56dfedd522
41 changed files with 7931 additions and 952 deletions

View File

@@ -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:

View File

@@ -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
@@ -186,7 +187,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
@@ -285,11 +286,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)
@@ -328,7 +330,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)
@@ -563,6 +565,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
@@ -1198,7 +1207,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 {
@@ -1695,12 +1704,20 @@ 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
"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 mapboxToken: String @isAuthorized
shareToken(credentials: ShareTokenCredentials!): ShareToken! shareToken(credentials: ShareTokenCredentials!): ShareToken!
shareTokenValidatePassword(credentials: ShareTokenCredentials!): Boolean! shareTokenValidatePassword(credentials: ShareTokenCredentials!): Boolean!
@@ -1945,6 +1962,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!]!
@@ -2778,6 +2797,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
} }
@@ -4002,14 +4030,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)
@@ -4021,9 +4049,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.marshalNAlbum2githubᚗ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) {
@@ -4160,6 +4188,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 {
@@ -6923,7 +6986,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 {
@@ -6939,10 +7002,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)
@@ -6954,9 +7017,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) {
@@ -7031,8 +7094,28 @@ func (ec *executionContext) _Query_mapboxToken(ctx context.Context, field graphq
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 directive0 := func(rctx context.Context) (interface{}, error) {
return ec.resolvers.Query().MapboxToken(rctx) ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().MapboxToken(rctx)
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAuthorized == nil {
return nil, errors.New("directive isAuthorized is not implemented")
}
return ec.directives.IsAuthorized(ctx, nil, directive0)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*string); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -10367,10 +10450,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) {
@@ -10412,6 +10504,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) {
@@ -12247,53 +12344,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)
} }

View File

@@ -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 (

View File

@@ -115,6 +115,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 {

View File

@@ -2,135 +2,160 @@ 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 query = models.FormatSQL(query, nil, paginate)
var media []*models.Media
if err := query.Find(&media).Error; err != nil {
return nil, err
}
return media, nil
} }
// func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Pagination, onlyFavorites *bool) ([]*models.TimelineGroup, error) {
// user := auth.UserFromContext(ctx)
// if user == nil {
// return nil, auth.ErrUnauthorized
// }
// var timelineGroups []*models.TimelineGroup
// transactionError := r.Database.Transaction(func(tx *gorm.DB) error {
// // album_id, year, month, day
// 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
// }

View File

@@ -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
@@ -313,6 +321,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!]!

6896
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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)"
}, },
@@ -74,7 +74,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",

View File

@@ -3,101 +3,101 @@
// @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";
/** /**
* 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 {
@@ -105,14 +105,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;
} }

View File

@@ -9,6 +9,9 @@
export interface CheckInitialSetup_siteInfo { export interface CheckInitialSetup_siteInfo {
__typename: "SiteInfo"; __typename: "SiteInfo";
/**
* Whether or not the initial setup wizard should be shown
*/
initialSetup: boolean; initialSetup: boolean;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -1,6 +1,5 @@
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'
const PhotosPage = () => { const PhotosPage = () => {
@@ -9,7 +8,7 @@ const PhotosPage = () => {
return ( return (
<> <>
<Layout title={t('photos_page.title', 'Photos')}> <Layout title={t('photos_page.title', 'Photos')}>
<TimelineGallery /> {/* <TimelineGallery /> */}
</Layout> </Layout>
</> </>
) )

View File

@@ -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[];
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -3,178 +3,178 @@
// @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";
/** /**
* 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 {
@@ -182,15 +182,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;
} }

View File

@@ -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",
Russian = 'Russian', Portuguese = "Portuguese",
Spanish = 'Spanish', Russian = "Russian",
Swedish = 'Swedish', SimplifiedChinese = "SimplifiedChinese",
TraditionalChinese = 'TraditionalChinese', Spanish = "Spanish",
SimplifiedChinese = 'SimplifiedChinese', Swedish = "Swedish",
Portuguese = 'Portuguese', 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",
} }
//============================================================== //==============================================================

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -0,0 +1,20 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: faceDetectionEnabled
// ====================================================
export interface faceDetectionEnabled_siteInfo {
__typename: "SiteInfo";
/**
* Whether or not face detection is enabled and working
*/
faceDetectionEnabled: boolean;
}
export interface faceDetectionEnabled {
siteInfo: faceDetectionEnabled_siteInfo;
}

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -27,30 +27,27 @@ const MY_TIMELINE_QUERY = gql`
onlyFavorites: $onlyFavorites onlyFavorites: $onlyFavorites
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 +60,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 = () => {
@@ -95,7 +98,7 @@ const TimelineGallery = () => {
variables: { variables: {
onlyFavorites, onlyFavorites,
offset: 0, offset: 0,
limit: 50, limit: 200,
}, },
}) })

View File

@@ -3,92 +3,95 @@
// @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: 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 {
__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'
id: string
title: string
type: MediaType
/**
* URL to display the media in a smaller resolution
*/
thumbnail: myTimeline_myTimeline_media_thumbnail | null
/**
* URL to display the photo in full resolution, will be null for videos
*/
highRes: myTimeline_myTimeline_media_highRes | null
/**
* 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
favorite: boolean
} }
export interface myTimeline_myTimeline { export interface myTimeline_myTimeline {
__typename: 'TimelineGroup' __typename: "Media";
album: myTimeline_myTimeline_album id: string;
media: myTimeline_myTimeline_media[] title: string;
mediaTotal: number type: MediaType;
date: any /**
* URL to display the media in a smaller resolution
*/
thumbnail: myTimeline_myTimeline_thumbnail | null;
/**
* URL to display the photo in full resolution, will be null for videos
*/
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
*/
videoWeb: myTimeline_myTimeline_videoWeb | null;
favorite: boolean;
/**
* The album that holds the media
*/
album: myTimeline_myTimeline_album;
/**
* The date the image was shot or the date it was imported as a fallback
*/
date: any;
} }
export interface myTimeline { export interface myTimeline {
myTimeline: myTimeline_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[];
} }
export interface myTimelineVariables { export interface myTimelineVariables {
onlyFavorites?: boolean | null onlyFavorites?: boolean | null;
limit?: number | null limit?: number | null;
offset?: number | null offset?: number | null;
} }

View File

@@ -19,120 +19,114 @@ describe('timeline gallery reducer', () => {
const timelineData: myTimeline_myTimeline[] = [ const timelineData: myTimeline_myTimeline[] = [
{ {
album: { __typename: 'Media',
id: '5', id: '1058',
title: 'first album', title: '122A2876.jpg',
__typename: 'Album', type: MediaType.Photo,
thumbnail: {
__typename: 'MediaURL',
url: 'http://localhost:4001/photo/thumbnail_122A2876_jpg_Kp1U80vD.jpg',
width: 1024,
height: 682,
}, },
media: [ highRes: {
{ __typename: 'MediaURL',
id: '165', url: 'http://localhost:4001/photo/122A2876_5cSPMiKL.jpg',
title: '3666760020.jpg', width: 6720,
type: MediaType.Photo, height: 4480,
thumbnail: { },
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg', videoWeb: null,
width: 768, favorite: false,
height: 1024, album: { __typename: 'Album', id: '522', title: 'random' },
__typename: 'MediaURL', date: '2020-12-13T18:03:40Z',
},
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: { __typename: 'Media',
id: '5', id: '1059',
title: 'another album', title: '122A2630-Edit.jpg',
__typename: 'Album', type: MediaType.Photo,
thumbnail: {
__typename: 'MediaURL',
url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_pwjtMkpy.jpg',
width: 1024,
height: 682,
}, },
media: [ highRes: {
{ __typename: 'MediaURL',
id: '165', url: 'http://localhost:4001/photo/122A2630-Edit_ySQWFAgE.jpg',
title: '3666760020.jpg', width: 6177,
type: MediaType.Photo, height: 4118,
thumbnail: { },
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg', videoWeb: null,
width: 768, favorite: false,
height: 1024, album: { __typename: 'Album', id: '523', title: 'another_album' },
__typename: 'MediaURL', date: '2020-11-25T16:14:33Z',
},
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', __typename: 'Media',
album: { id: '1060',
__typename: 'Album', title: '122A2785-2.jpg',
id: '5', type: MediaType.Photo,
title: 'album on another day', thumbnail: {
__typename: 'MediaURL',
url: 'http://localhost:4001/photo/thumbnail_122A2785-2_jpg_CevmxEXf.jpg',
width: 1024,
height: 1024,
}, },
date: '2019-09-13T00:00:00Z', highRes: {
mediaTotal: 1, __typename: 'MediaURL',
media: [ url: 'http://localhost:4001/photo/122A2785-2_mCnWjLdb.jpg',
{ width: 884,
__typename: 'Media', height: 884,
favorite: false, },
videoWeb: null, videoWeb: null,
thumbnail: { favorite: false,
url: 'http://localhost:4001/photo/thumbnail_3666760020_jpg_x76GG5pS.jpg', album: { __typename: 'Album', id: '523', title: 'another_album' },
width: 768, date: '2020-11-25T16:43:59Z',
height: 1024, },
__typename: 'MediaURL', {
}, __typename: 'Media',
highRes: { id: '1056',
url: 'http://localhost:4001/photo/3666760020_wijGDNZ2.jpg', title: '122A2630-Edit.jpg',
width: 3024, type: MediaType.Photo,
height: 4032, thumbnail: {
__typename: 'MediaURL', __typename: 'MediaURL',
}, url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_aJPCSDDl.jpg',
id: '321', width: 1024,
title: 'asdfimg.jpg', height: 682,
type: MediaType.Photo, },
}, 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',
}, },
] ]
@@ -150,72 +144,102 @@ describe('timeline gallery reducer', () => {
media: -1, media: -1,
}, },
timelineGroups: [ timelineGroups: [
{ // {
date: '2019-09-21T00:00:00Z', // date: '2020-12-13T00:00:00Z',
groups: [ // albums: [
{ // {
album: { // id: '522',
id: '5', // title: 'random',
title: 'first album', // media: [
}, // {
date: '2019-09-21T00:00:00Z', // __typename: 'Media',
media: [ // id: '1058',
{ // title: '122A2876.jpg',
favorite: false, // type: MediaType.Photo,
highRes: {}, // thumbnail: {
id: '165', // __typename: 'MediaURL',
thumbnail: {}, // url: 'http://localhost:4001/photo/thumbnail_122A2876_jpg_Kp1U80vD.jpg',
title: '3666760020.jpg', // width: 1024,
type: 'Photo', // height: 682,
}, // },
{ // highRes: {
highRes: {}, // __typename: 'MediaURL',
id: '184', // url: 'http://localhost:4001/photo/122A2876_5cSPMiKL.jpg',
thumbnail: {}, // width: 6720,
title: '7414455077.jpg', // height: 4480,
type: 'Photo', // },
}, // videoWeb: null,
], // favorite: false,
mediaTotal: 5, // album: { __typename: 'Album', id: '522', title: 'random' },
}, // date: '2020-12-13T18:03:40Z',
{ // },
album: { // ],
id: '5', // },
title: 'another album', // ],
}, // },
date: '2019-09-21T00:00:00Z', // {
media: [ // date: '2020-11-25T00:00:00Z',
{ // albums: [
id: '165', // {
}, // id: '523',
], // title: 'another_album',
mediaTotal: 7, // media: [
}, // {
], // __typename: 'Media',
}, // id: '1059',
{ // title: '122A2630-Edit.jpg',
date: '2019-09-13T00:00:00Z', // type: MediaType.Photo,
groups: [ // thumbnail: {
{ // __typename: 'MediaURL',
album: { // url: 'http://localhost:4001/photo/thumbnail_122A2630-Edit_jpg_pwjtMkpy.jpg',
id: '5', // width: 1024,
title: 'album on another day', // height: 682,
}, // },
date: '2019-09-13T00:00:00Z', // highRes: {
media: [ // __typename: 'MediaURL',
{ // url: 'http://localhost:4001/photo/122A2630-Edit_ySQWFAgE.jpg',
favorite: false, // width: 6177,
highRes: {}, // height: 4118,
id: '321', // },
thumbnail: {}, // videoWeb: null,
title: 'asdfimg.jpg', // favorite: false,
type: 'Photo', // album: {
}, // __typename: 'Album',
], // id: '523',
mediaTotal: 1, // 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',
// },
// ],
// },
// ],
// },
], ],
}) })
}) })

View File

@@ -1,9 +1,6 @@
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'
export interface TimelineMediaIndex { export interface TimelineMediaIndex {
@@ -30,18 +27,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 +36,7 @@ export function timelineGalleryReducer(
date: -1, date: -1,
media: -1, media: -1,
}, },
timelineGroups: dateGroupedAlbums, timelineGroups,
} }
} }
case 'nextImage': { case 'nextImage': {
@@ -64,7 +50,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 +110,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 +124,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 +167,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 +189,65 @@ 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)
}
return timelineGroups
}
export const openTimelinePresentMode = ({ export const openTimelinePresentMode = ({
dispatchMedia, dispatchMedia,
activeIndex, activeIndex,