mirror of
https://git.vectorsigma.ru/public/photoview.git
synced 2026-08-03 21:09:05 +00:00
Add graphql query for getting media from an array of ids
- Add keyboard navigation when presenting images in map view
This commit is contained in:
@@ -146,6 +146,7 @@ type ComplexityRoot struct {
|
|||||||
Album func(childComplexity int, id int) int
|
Album func(childComplexity int, id int) int
|
||||||
MapboxToken func(childComplexity int) int
|
MapboxToken func(childComplexity int) int
|
||||||
Media func(childComplexity int, id int) int
|
Media func(childComplexity int, id int) int
|
||||||
|
MediaList func(childComplexity int, ids []int) int
|
||||||
MyAlbums func(childComplexity int, filter *models.Filter, onlyRoot *bool, showEmpty *bool, onlyWithFavorites *bool) int
|
MyAlbums func(childComplexity int, filter *models.Filter, onlyRoot *bool, showEmpty *bool, onlyWithFavorites *bool) int
|
||||||
MyMedia func(childComplexity int, filter *models.Filter) int
|
MyMedia func(childComplexity int, filter *models.Filter) int
|
||||||
MyMediaGeoJSON func(childComplexity int) int
|
MyMediaGeoJSON func(childComplexity int) int
|
||||||
@@ -257,6 +258,7 @@ type QueryResolver interface {
|
|||||||
Album(ctx context.Context, id int) (*models.Album, error)
|
Album(ctx context.Context, id int) (*models.Album, error)
|
||||||
MyMedia(ctx context.Context, filter *models.Filter) ([]*models.Media, error)
|
MyMedia(ctx context.Context, filter *models.Filter) ([]*models.Media, error)
|
||||||
Media(ctx context.Context, id int) (*models.Media, error)
|
Media(ctx context.Context, id int) (*models.Media, error)
|
||||||
|
MediaList(ctx context.Context, ids []int) ([]*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, token string, password *string) (*models.ShareToken, error)
|
ShareToken(ctx context.Context, token string, password *string) (*models.ShareToken, error)
|
||||||
@@ -869,6 +871,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.Query.Media(childComplexity, args["id"].(int)), true
|
return e.complexity.Query.Media(childComplexity, args["id"].(int)), true
|
||||||
|
|
||||||
|
case "Query.mediaList":
|
||||||
|
if e.complexity.Query.MediaList == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Query_mediaList_args(context.TODO(), rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Query.MediaList(childComplexity, args["ids"].([]int)), true
|
||||||
|
|
||||||
case "Query.myAlbums":
|
case "Query.myAlbums":
|
||||||
if e.complexity.Query.MyAlbums == nil {
|
if e.complexity.Query.MyAlbums == nil {
|
||||||
break
|
break
|
||||||
@@ -1310,6 +1324,9 @@ type Query {
|
|||||||
"Get media by id, user must own the media or be admin"
|
"Get media by id, user must own the media or be admin"
|
||||||
media(id: Int!): Media!
|
media(id: Int!): Media!
|
||||||
|
|
||||||
|
"Get a list of media by their ids, user must own the media or be admin"
|
||||||
|
mediaList(ids: [Int!]!): [Media!]!
|
||||||
|
|
||||||
"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!
|
myMediaGeoJson: Any!
|
||||||
"Get the mapbox api token, returns null if mapbox is not enabled"
|
"Get the mapbox api token, returns null if mapbox is not enabled"
|
||||||
@@ -1584,6 +1601,7 @@ func (ec *executionContext) field_Album_media_args(ctx context.Context, rawArgs
|
|||||||
args["filter"] = arg0
|
args["filter"] = arg0
|
||||||
var arg1 *bool
|
var arg1 *bool
|
||||||
if tmp, ok := rawArgs["onlyFavorites"]; ok {
|
if tmp, ok := rawArgs["onlyFavorites"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("onlyFavorites"))
|
||||||
arg1, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
|
arg1, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -2010,6 +2028,21 @@ func (ec *executionContext) field_Query_album_args(ctx context.Context, rawArgs
|
|||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Query_mediaList_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]interface{}{}
|
||||||
|
var arg0 []int
|
||||||
|
if tmp, ok := rawArgs["ids"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids"))
|
||||||
|
arg0, err = ec.unmarshalNInt2ᚕintᚄ(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["ids"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_media_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Query_media_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
@@ -2057,6 +2090,7 @@ func (ec *executionContext) field_Query_myAlbums_args(ctx context.Context, rawAr
|
|||||||
args["showEmpty"] = arg2
|
args["showEmpty"] = arg2
|
||||||
var arg3 *bool
|
var arg3 *bool
|
||||||
if tmp, ok := rawArgs["onlyWithFavorites"]; ok {
|
if tmp, ok := rawArgs["onlyWithFavorites"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("onlyWithFavorites"))
|
||||||
arg3, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
|
arg3, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -4965,6 +4999,48 @@ func (ec *executionContext) _Query_media(ctx context.Context, field graphql.Coll
|
|||||||
return ec.marshalNMedia2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx, field.Selections, res)
|
return ec.marshalNMedia2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Query_mediaList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "Query",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
rawArgs := field.ArgumentMap(ec.Variables)
|
||||||
|
args, err := ec.field_Query_mediaList_args(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
fc.Args = args
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Query().MediaList(rctx, args["ids"].([]int))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*models.Media)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNMedia2ᚕᚖgithubᚗcomᚋviktorstrateᚋ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) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@@ -8204,6 +8280,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
case "mediaList":
|
||||||
|
field := field
|
||||||
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._Query_mediaList(ctx, field)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
case "myMediaGeoJson":
|
case "myMediaGeoJson":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
@@ -8975,6 +9065,36 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNInt2ᚕintᚄ(ctx context.Context, v interface{}) ([]int, error) {
|
||||||
|
var vSlice []interface{}
|
||||||
|
if v != nil {
|
||||||
|
if tmp1, ok := v.([]interface{}); ok {
|
||||||
|
vSlice = tmp1
|
||||||
|
} else {
|
||||||
|
vSlice = []interface{}{v}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
res := make([]int, len(vSlice))
|
||||||
|
for i := range vSlice {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i))
|
||||||
|
res[i], err = ec.unmarshalNInt2int(ctx, vSlice[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNInt2ᚕintᚄ(ctx context.Context, sel ast.SelectionSet, v []int) graphql.Marshaler {
|
||||||
|
ret := make(graphql.Array, len(v))
|
||||||
|
for i := range v {
|
||||||
|
ret[i] = ec.marshalNInt2int(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNMedia2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx context.Context, sel ast.SelectionSet, v models.Media) graphql.Marshaler {
|
func (ec *executionContext) marshalNMedia2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx context.Context, sel ast.SelectionSet, v models.Media) graphql.Marshaler {
|
||||||
return ec._Media(ctx, sel, &v)
|
return ec._Media(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,44 @@ func (r *queryResolver) Media(ctx context.Context, id int) (*models.Media, error
|
|||||||
return media, nil
|
return media, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *queryResolver) MediaList(ctx context.Context, ids []int) ([]*models.Media, error) {
|
||||||
|
user := auth.UserFromContext(ctx)
|
||||||
|
if user == nil {
|
||||||
|
return nil, auth.ErrUnauthorized
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil, errors.New("no ids provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaIDQuestions := strings.Repeat("?,", len(ids))[:len(ids)*2-1]
|
||||||
|
|
||||||
|
queryArgs := make([]interface{}, 0)
|
||||||
|
for _, id := range ids {
|
||||||
|
queryArgs = append(queryArgs, id)
|
||||||
|
}
|
||||||
|
queryArgs = append(queryArgs, user.UserID)
|
||||||
|
|
||||||
|
rows, err := r.Database.Query(`
|
||||||
|
SELECT media.* FROM media
|
||||||
|
JOIN album ON media.album_id = album.album_id
|
||||||
|
WHERE media.media_id IN (`+mediaIDQuestions+`) AND album.owner_id = ?
|
||||||
|
AND media.media_id IN (
|
||||||
|
SELECT media_id FROM media_url WHERE media_url.media_id = media.media_id
|
||||||
|
)
|
||||||
|
`, queryArgs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not get media list by media_id and user_id from database")
|
||||||
|
}
|
||||||
|
|
||||||
|
media, err := models.NewMediaFromRows(rows)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not convert database rows to media")
|
||||||
|
}
|
||||||
|
|
||||||
|
return media, nil
|
||||||
|
}
|
||||||
|
|
||||||
type mediaResolver struct {
|
type mediaResolver struct {
|
||||||
*Resolver
|
*Resolver
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ type Query {
|
|||||||
"Get media by id, user must own the media or be admin"
|
"Get media by id, user must own the media or be admin"
|
||||||
media(id: Int!): Media!
|
media(id: Int!): Media!
|
||||||
|
|
||||||
|
"Get a list of media by their ids, user must own the media or be admin"
|
||||||
|
mediaList(ids: [Int!]!): [Media!]!
|
||||||
|
|
||||||
"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!
|
myMediaGeoJson: Any!
|
||||||
"Get the mapbox api token, returns null if mapbox is not enabled"
|
"Get the mapbox api token, returns null if mapbox is not enabled"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { useLazyQuery } from 'react-apollo'
|
|||||||
import PresentView from '../../components/photoGallery/presentView/PresentView'
|
import PresentView from '../../components/photoGallery/presentView/PresentView'
|
||||||
|
|
||||||
const QUERY_MEDIA = gql`
|
const QUERY_MEDIA = gql`
|
||||||
query placePageQueryMedia($mediaID: Int!) {
|
query placePageQueryMedia($mediaIDs: [Int!]!) {
|
||||||
media(id: $mediaID) {
|
mediaList(ids: $mediaIDs) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
thumbnail {
|
thumbnail {
|
||||||
@@ -53,74 +53,51 @@ const getMediaFromMarker = (map, presentMarker) =>
|
|||||||
})
|
})
|
||||||
|
|
||||||
const MapPresentMarker = ({ map, presentMarker, setPresentMarker }) => {
|
const MapPresentMarker = ({ map, presentMarker, setPresentMarker }) => {
|
||||||
const [media, setMedia] = useState(null)
|
const [mediaMarkers, setMediaMarkers] = useState(null)
|
||||||
const [currentIndex, setCurrentIndex] = useState(0)
|
const [currentIndex, setCurrentIndex] = useState(0)
|
||||||
|
|
||||||
const previousLoadedMedia = useRef(null)
|
const [loadMedia, { data: loadedMedia }] = useLazyQuery(QUERY_MEDIA)
|
||||||
const [loadMedia, { data: loadedMedia }] = useLazyQuery(QUERY_MEDIA, {
|
|
||||||
onCompleted(data) {
|
|
||||||
previousLoadedMedia.current = data
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (presentMarker == null || map == null) {
|
if (presentMarker == null || map == null) {
|
||||||
setMedia(null)
|
setMediaMarkers(null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
getMediaFromMarker(map, presentMarker).then(setMedia)
|
getMediaFromMarker(map, presentMarker).then(setMediaMarkers)
|
||||||
}, [presentMarker])
|
}, [presentMarker])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!media) return
|
if (!mediaMarkers) return
|
||||||
|
|
||||||
setCurrentIndex(0)
|
setCurrentIndex(0)
|
||||||
loadMedia({
|
loadMedia({
|
||||||
variables: {
|
variables: {
|
||||||
mediaID: media[0].media_id,
|
mediaIDs: mediaMarkers.map(x => x.media_id),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}, [media])
|
}, [mediaMarkers])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!media) return
|
|
||||||
|
|
||||||
console.log('Current index change', currentIndex, media)
|
|
||||||
|
|
||||||
loadMedia({
|
|
||||||
variables: {
|
|
||||||
mediaID: media[currentIndex].media_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}, [currentIndex])
|
|
||||||
|
|
||||||
if (presentMarker == null || map == null) {
|
if (presentMarker == null || map == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadedMedia == null && previousLoadedMedia.current == null) {
|
if (loadedMedia == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayMedia = loadedMedia
|
|
||||||
? loadedMedia.media
|
|
||||||
: previousLoadedMedia.current.media
|
|
||||||
|
|
||||||
console.log('diaplay media', displayMedia)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PresentView
|
<PresentView
|
||||||
media={displayMedia}
|
media={loadedMedia.mediaList[currentIndex]}
|
||||||
nextImage={() => {
|
nextImage={() => {
|
||||||
setCurrentIndex(i => Math.min(media.length - 1, i + 1))
|
setCurrentIndex(i => Math.min(mediaMarkers.length - 1, i + 1))
|
||||||
}}
|
}}
|
||||||
previousImage={() => {
|
previousImage={() => {
|
||||||
setCurrentIndex(i => Math.max(0, i - 1))
|
setCurrentIndex(i => Math.max(0, i - 1))
|
||||||
}}
|
}}
|
||||||
setPresenting={presenting => {
|
setPresenting={presenting => {
|
||||||
if (!presenting) {
|
if (!presenting) {
|
||||||
previousLoadedMedia.current = null
|
setCurrentIndex(0)
|
||||||
setPresentMarker(null)
|
setPresentMarker(null)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -61,12 +61,10 @@ const MapPage = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
map.current.on('load', () => {
|
map.current.on('load', () => {
|
||||||
console.log(mapboxData.myMediaGeoJson)
|
|
||||||
map.current.addSource('media', {
|
map.current.addSource('media', {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
data: mapboxData.myMediaGeoJson,
|
data: mapboxData.myMediaGeoJson,
|
||||||
cluster: true,
|
cluster: true,
|
||||||
// clusterMaxZoom: 14, // Max zoom to cluster points on
|
|
||||||
clusterRadius: 50,
|
clusterRadius: 50,
|
||||||
clusterProperties: {
|
clusterProperties: {
|
||||||
thumbnail: ['coalesce', ['get', 'thumbnail'], false],
|
thumbnail: ['coalesce', ['get', 'thumbnail'], false],
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ export const makeUpdateMarkers = ({
|
|||||||
for (let i = 0; i < features.length; i++) {
|
for (let i = 0; i < features.length; i++) {
|
||||||
const coords = features[i].geometry.coordinates
|
const coords = features[i].geometry.coordinates
|
||||||
const props = features[i].properties
|
const props = features[i].properties
|
||||||
const id = props.cluster ? props.cluster_id : props.media_id
|
const id = props.cluster
|
||||||
|
? `cluster_${props.cluster_id}`
|
||||||
|
: `media_${props.media_id}`
|
||||||
|
|
||||||
let marker = markers[id]
|
let marker = markers[id]
|
||||||
if (!marker) {
|
if (!marker) {
|
||||||
|
|||||||
@@ -44,32 +44,6 @@ const PhotoGallery = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { updateSidebar } = useContext(SidebarContext)
|
const { updateSidebar } = useContext(SidebarContext)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const keyDownEvent = e => {
|
|
||||||
if (!onSelectImage || activeIndex == -1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.key == 'ArrowRight') {
|
|
||||||
nextImage && nextImage()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.key == 'ArrowLeft') {
|
|
||||||
nextImage && previousImage()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.key == 'Escape' && presenting) {
|
|
||||||
setPresenting(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('keydown', keyDownEvent)
|
|
||||||
|
|
||||||
return function cleanup() {
|
|
||||||
document.removeEventListener('keydown', keyDownEvent)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const activeImage = media && activeIndex != -1 && media[activeIndex]
|
const activeImage = media && activeIndex != -1 && media[activeIndex]
|
||||||
|
|
||||||
const getPhotoElements = updateSidebar => {
|
const getPhotoElements = updateSidebar => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import React, { useEffect } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React from 'react'
|
|
||||||
import styled, { createGlobalStyle } from 'styled-components'
|
import styled, { createGlobalStyle } from 'styled-components'
|
||||||
import PresentNavigationOverlay from './PresentNavigationOverlay'
|
import PresentNavigationOverlay from './PresentNavigationOverlay'
|
||||||
import PresentMedia from './PresentMedia'
|
import PresentMedia from './PresentMedia'
|
||||||
@@ -28,14 +28,43 @@ const PresentView = ({
|
|||||||
nextImage,
|
nextImage,
|
||||||
previousImage,
|
previousImage,
|
||||||
setPresenting,
|
setPresenting,
|
||||||
}) => (
|
}) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const keyDownEvent = e => {
|
||||||
|
if (e.key == 'ArrowRight') {
|
||||||
|
nextImage && nextImage()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.key == 'ArrowLeft') {
|
||||||
|
nextImage && previousImage()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.key == 'Escape') {
|
||||||
|
setPresenting(false)
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('keydown', keyDownEvent)
|
||||||
|
|
||||||
|
return function cleanup() {
|
||||||
|
document.removeEventListener('keydown', keyDownEvent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
<StyledContainer {...className}>
|
<StyledContainer {...className}>
|
||||||
<PreventScroll />
|
<PreventScroll />
|
||||||
<PresentNavigationOverlay {...{ nextImage, previousImage, setPresenting }}>
|
<PresentNavigationOverlay
|
||||||
|
{...{ nextImage, previousImage, setPresenting }}
|
||||||
|
>
|
||||||
<PresentMedia media={media} imageLoaded={imageLoaded} />
|
<PresentMedia media={media} imageLoaded={imageLoaded} />
|
||||||
</PresentNavigationOverlay>
|
</PresentNavigationOverlay>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
PresentView.propTypes = {
|
PresentView.propTypes = {
|
||||||
media: PropTypes.object.isRequired,
|
media: PropTypes.object.isRequired,
|
||||||
|
|||||||
Reference in New Issue
Block a user