- Performance optimizations - restructured the code so no necessary Layout and AlbumFilter component rerenderings are made.
This commit is contained in:
parent
a290392894
commit
55885ddb65
|
@ -59,49 +59,35 @@ function AlbumPage({ match }) {
|
|||
match.params.subPage === 'favorites'
|
||||
)
|
||||
|
||||
const [orderBy, setOrderBy] = useState('date_shot')
|
||||
const [orderDirection, setOrderDirection] = useState('ASC')
|
||||
|
||||
const setSorting = useCallback(
|
||||
(d, refetch) => {
|
||||
const [orderBy, orderDirection] = d.value.split('.')
|
||||
setOrderBy(orderBy)
|
||||
setOrderDirection(orderDirection)
|
||||
refetch({
|
||||
id: albumId,
|
||||
onlyFavorites,
|
||||
mediaOrderBy: orderBy,
|
||||
mediaOrderDirection: orderDirection,
|
||||
})
|
||||
},
|
||||
[albumId, onlyFavorites, setOrderBy, setOrderDirection]
|
||||
)
|
||||
const [ordering, setOrdering] = useState({
|
||||
orderBy: 'date_shot',
|
||||
orderDirection: 'ASC',
|
||||
})
|
||||
|
||||
const toggleFavorites = useCallback(
|
||||
refetch => {
|
||||
const newState = !onlyFavorites
|
||||
(onlyFavorites, refetch) => {
|
||||
if (
|
||||
(refetchNeededAll && !newState) ||
|
||||
(refetchNeededFavorites && newState)
|
||||
(refetchNeededAll && !onlyFavorites) ||
|
||||
(refetchNeededFavorites && onlyFavorites)
|
||||
) {
|
||||
refetch({ id: albumId, onlyFavorites: newState }).then(() => {
|
||||
refetch({ id: albumId, onlyFavorites: onlyFavorites }).then(() => {
|
||||
if (onlyFavorites) {
|
||||
refetchNeededFavorites = false
|
||||
} else {
|
||||
refetchNeededAll = false
|
||||
}
|
||||
setOnlyFavorites(newState)
|
||||
setOnlyFavorites(onlyFavorites)
|
||||
})
|
||||
} else {
|
||||
setOnlyFavorites(newState)
|
||||
setOnlyFavorites(onlyFavorites)
|
||||
}
|
||||
history.replaceState(
|
||||
{},
|
||||
'',
|
||||
'/album/' + albumId + (newState ? '/favorites' : '')
|
||||
'/album/' + albumId + (onlyFavorites ? '/favorites' : '')
|
||||
)
|
||||
},
|
||||
[onlyFavorites, setOnlyFavorites]
|
||||
[setOnlyFavorites]
|
||||
)
|
||||
|
||||
return (
|
||||
|
@ -110,8 +96,8 @@ function AlbumPage({ match }) {
|
|||
variables={{
|
||||
id: albumId,
|
||||
onlyFavorites,
|
||||
mediaOrderBy: orderBy,
|
||||
mediaOrderDirection: orderDirection,
|
||||
mediaOrderBy: ordering.orderBy,
|
||||
mediaOrderDirection: ordering.orderDirection,
|
||||
}}
|
||||
>
|
||||
{({ loading, error, data, refetch }) => {
|
||||
|
@ -121,15 +107,15 @@ function AlbumPage({ match }) {
|
|||
album={data && data.album}
|
||||
loading={loading}
|
||||
showFavoritesToggle
|
||||
setOnlyFavorites={() => {
|
||||
toggleFavorites(refetch)
|
||||
setOnlyFavorites={checked => {
|
||||
toggleFavorites(checked, refetch)
|
||||
}}
|
||||
onlyFavorites={onlyFavorites}
|
||||
onFavorite={() =>
|
||||
(refetchNeededAll = refetchNeededFavorites = true)
|
||||
}
|
||||
showFilter
|
||||
setSorting={(e, d) => setSorting(d, refetch)}
|
||||
setOrdering={setOrdering}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -1,176 +1,13 @@
|
|||
import React, { useCallback, useRef, useState } from 'react'
|
||||
import React from 'react'
|
||||
import Layout from '../../Layout'
|
||||
import gql from 'graphql-tag'
|
||||
import { useQuery } from 'react-apollo'
|
||||
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
|
||||
import AlbumTitle from '../../components/AlbumTitle'
|
||||
import { authToken } from '../../authentication'
|
||||
import PropTypes from 'prop-types'
|
||||
import AlbumFilter from '../../components/AlbumFilter'
|
||||
|
||||
const photoQuery = gql`
|
||||
query allPhotosPage(
|
||||
$onlyWithFavorites: Boolean
|
||||
$mediaOrderBy: String
|
||||
$mediaOrderDirection: OrderDirection
|
||||
) {
|
||||
myAlbums(
|
||||
filter: { order_by: "title", order_direction: ASC, limit: 100 }
|
||||
onlyWithFavorites: $onlyWithFavorites
|
||||
) {
|
||||
title
|
||||
id
|
||||
media(
|
||||
filter: {
|
||||
order_by: $mediaOrderBy
|
||||
order_direction: $mediaOrderDirection
|
||||
limit: 12
|
||||
}
|
||||
onlyFavorites: $onlyWithFavorites
|
||||
) {
|
||||
id
|
||||
title
|
||||
type
|
||||
thumbnail {
|
||||
url
|
||||
width
|
||||
height
|
||||
}
|
||||
highRes {
|
||||
url
|
||||
width
|
||||
height
|
||||
}
|
||||
videoWeb {
|
||||
url
|
||||
}
|
||||
favorite
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
import GalleryGroups from '../../components/photoGallery/GalleryGroups'
|
||||
|
||||
const PhotosPage = ({ match }) => {
|
||||
const [activeIndex, setActiveIndex] = useState({ album: -1, media: -1 })
|
||||
const [presenting, setPresenting] = useState(false)
|
||||
const [onlyWithFavorites, setOnlyWithFavorites] = useState(
|
||||
match.params.subPage === 'favorites'
|
||||
)
|
||||
|
||||
const refetchNeeded = useRef({ all: false, favorites: false })
|
||||
|
||||
const [orderBy, setOrderBy] = useState('date_shot')
|
||||
const [orderDirection, setOrderDirection] = useState('ASC')
|
||||
|
||||
const { loading, error, data, refetch } = useQuery(photoQuery, {
|
||||
variables: {
|
||||
onlyWithFavorites: onlyWithFavorites,
|
||||
mediaOrderBy: orderBy,
|
||||
mediaOrderDirection: orderDirection,
|
||||
},
|
||||
})
|
||||
|
||||
const setSorting = useCallback(
|
||||
(e, d) => {
|
||||
const [orderBy, orderDirection] = d.value.split('.')
|
||||
setOrderBy(orderBy)
|
||||
setOrderDirection(orderDirection)
|
||||
refetch({
|
||||
onlyWithFavorites: onlyWithFavorites,
|
||||
mediaOrderBy: orderBy,
|
||||
mediaOrderDirection: orderDirection,
|
||||
})
|
||||
},
|
||||
[refetch, setOrderBy, setOrderDirection]
|
||||
)
|
||||
|
||||
const nextImage = useCallback(() => {
|
||||
setActiveIndex(index => {
|
||||
const albumMediaCount = data.myAlbums[index.album].media.length
|
||||
|
||||
if (index.media + 1 < albumMediaCount) {
|
||||
return {
|
||||
...index,
|
||||
media: index.media + 1,
|
||||
}
|
||||
} else {
|
||||
return index
|
||||
}
|
||||
})
|
||||
}, [data])
|
||||
|
||||
const previousImage = useCallback(() => {
|
||||
setActiveIndex(index =>
|
||||
index.media > 0 ? { ...index, media: index.media - 1 } : index
|
||||
)
|
||||
})
|
||||
|
||||
const setOnlyFavorites = useCallback(() => {
|
||||
const updatedWithFavorites = !onlyWithFavorites
|
||||
|
||||
history.replaceState(
|
||||
{},
|
||||
'',
|
||||
'/photos' + (updatedWithFavorites ? '/favorites' : '')
|
||||
)
|
||||
|
||||
if (
|
||||
(refetchNeeded.current.all && !updatedWithFavorites) ||
|
||||
(refetchNeeded.current.favorites && updatedWithFavorites)
|
||||
) {
|
||||
refetch({ onlyWithFavorites: updatedWithFavorites }).then(() => {
|
||||
if (updatedWithFavorites) {
|
||||
refetchNeeded.current.favorites = false
|
||||
} else {
|
||||
refetchNeeded.current.all = false
|
||||
}
|
||||
setOnlyWithFavorites(updatedWithFavorites)
|
||||
})
|
||||
} else {
|
||||
setOnlyWithFavorites(updatedWithFavorites)
|
||||
}
|
||||
}, [onlyWithFavorites])
|
||||
|
||||
if (error) return error
|
||||
if (loading) return null
|
||||
|
||||
let galleryGroups = []
|
||||
|
||||
if (data.myAlbums && authToken()) {
|
||||
galleryGroups = data.myAlbums.map((album, index) => (
|
||||
<div key={album.id}>
|
||||
<AlbumTitle album={album} />
|
||||
<PhotoGallery
|
||||
onSelectImage={mediaIndex => {
|
||||
setActiveIndex({ album: index, media: mediaIndex })
|
||||
}}
|
||||
onFavorite={() => {
|
||||
refetchNeeded.current.all = true
|
||||
refetchNeeded.current.favorites = true
|
||||
}}
|
||||
activeIndex={activeIndex.album === index ? activeIndex.media : -1}
|
||||
presenting={presenting === index}
|
||||
setPresenting={presenting =>
|
||||
setPresenting(presenting ? index : false)
|
||||
}
|
||||
loading={loading}
|
||||
media={album.media}
|
||||
nextImage={nextImage}
|
||||
previousImage={previousImage}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout title="Photos">
|
||||
<AlbumFilter
|
||||
onlyFavorites={onlyWithFavorites}
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
setSorting={setSorting}
|
||||
/>
|
||||
{galleryGroups}
|
||||
<GalleryGroups subPage={match.params.subPage} />
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -52,7 +52,7 @@ const FavoritesCheckbox = styled(Checkbox)`
|
|||
margin-right: 10px;
|
||||
`
|
||||
|
||||
const AlbumFilter = ({ onlyFavorites, setOnlyFavorites, setSorting }) => {
|
||||
const AlbumFilter = ({ onlyFavorites, setOnlyFavorites, setOrdering }) => {
|
||||
return (
|
||||
<>
|
||||
{authToken() && (
|
||||
|
@ -61,14 +61,17 @@ const AlbumFilter = ({ onlyFavorites, setOnlyFavorites, setSorting }) => {
|
|||
label="Show only favorites"
|
||||
checked={onlyFavorites}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={setOnlyFavorites}
|
||||
onChange={(e, result) => setOnlyFavorites(result.checked)}
|
||||
/>
|
||||
)}
|
||||
<strong> Sort by: </strong>
|
||||
<Dropdown
|
||||
options={sortingOptions}
|
||||
defaultValue={sortingOptions[0].value}
|
||||
onChange={setSorting}
|
||||
onChange={(e, d) => {
|
||||
const [orderBy, orderDirection] = d.value.split('.')
|
||||
setOrdering({ orderBy, orderDirection })
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
@ -77,7 +80,7 @@ const AlbumFilter = ({ onlyFavorites, setOnlyFavorites, setSorting }) => {
|
|||
AlbumFilter.propTypes = {
|
||||
onlyFavorites: PropTypes.bool,
|
||||
setOnlyFavorites: PropTypes.func,
|
||||
setSorting: PropTypes.func,
|
||||
setOrdering: PropTypes.func,
|
||||
}
|
||||
|
||||
export default React.memo(AlbumFilter)
|
||||
|
|
|
@ -12,7 +12,7 @@ const AlbumGallery = ({
|
|||
customAlbumLink,
|
||||
showFilter = false,
|
||||
setOnlyFavorites,
|
||||
setSorting,
|
||||
setOrdering,
|
||||
onlyFavorites = false,
|
||||
onFavorite,
|
||||
}) => {
|
||||
|
@ -93,7 +93,7 @@ const AlbumGallery = ({
|
|||
<AlbumFilter
|
||||
onlyFavorites={onlyFavorites}
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
setSorting={setSorting}
|
||||
setOrdering={setOrdering}
|
||||
/>
|
||||
)}
|
||||
{subAlbumElement}
|
||||
|
@ -132,7 +132,7 @@ AlbumGallery.propTypes = {
|
|||
setOnlyFavorites: PropTypes.func,
|
||||
onlyFavorites: PropTypes.bool,
|
||||
onFavorite: PropTypes.func,
|
||||
setSorting: PropTypes.func,
|
||||
setOrdering: PropTypes.func,
|
||||
}
|
||||
|
||||
export default AlbumGallery
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
import React, { useCallback, useRef, useState } from 'react'
|
||||
import gql from 'graphql-tag'
|
||||
import { useQuery } from 'react-apollo'
|
||||
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
|
||||
import AlbumTitle from '../../components/AlbumTitle'
|
||||
import { authToken } from '../../authentication'
|
||||
import PropTypes from 'prop-types'
|
||||
import AlbumFilter from '../../components/AlbumFilter'
|
||||
|
||||
const photoQuery = gql`
|
||||
query allGalleryGroups(
|
||||
$onlyWithFavorites: Boolean
|
||||
$mediaOrderBy: String
|
||||
$mediaOrderDirection: OrderDirection
|
||||
) {
|
||||
myAlbums(
|
||||
filter: { order_by: "title", order_direction: ASC, limit: 100 }
|
||||
onlyWithFavorites: $onlyWithFavorites
|
||||
) {
|
||||
title
|
||||
id
|
||||
media(
|
||||
filter: {
|
||||
order_by: $mediaOrderBy
|
||||
order_direction: $mediaOrderDirection
|
||||
limit: 12
|
||||
}
|
||||
onlyFavorites: $onlyWithFavorites
|
||||
) {
|
||||
id
|
||||
title
|
||||
type
|
||||
thumbnail {
|
||||
url
|
||||
width
|
||||
height
|
||||
}
|
||||
highRes {
|
||||
url
|
||||
width
|
||||
height
|
||||
}
|
||||
videoWeb {
|
||||
url
|
||||
}
|
||||
favorite
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const GalleryGroups = ({ subPage }) => {
|
||||
const [activeIndex, setActiveIndex] = useState({ album: -1, media: -1 })
|
||||
const [presenting, setPresenting] = useState(false)
|
||||
const [onlyWithFavorites, setOnlyWithFavorites] = useState(
|
||||
subPage === 'favorites'
|
||||
)
|
||||
const [ordering, setOrdering] = useState({
|
||||
orderBy: 'date_shot',
|
||||
orderDirection: 'ASC',
|
||||
})
|
||||
|
||||
const refetchNeeded = useRef({ all: false, favorites: false })
|
||||
|
||||
const { loading, error, data, refetch } = useQuery(photoQuery, {
|
||||
variables: {
|
||||
onlyWithFavorites: onlyWithFavorites,
|
||||
mediaOrderBy: ordering.orderBy,
|
||||
mediaOrderDirection: ordering.orderDirection,
|
||||
},
|
||||
})
|
||||
|
||||
const nextImage = useCallback(() => {
|
||||
setActiveIndex(index => {
|
||||
const albumMediaCount = data.myAlbums[index.album].media.length
|
||||
|
||||
if (index.media + 1 < albumMediaCount) {
|
||||
return {
|
||||
...index,
|
||||
media: index.media + 1,
|
||||
}
|
||||
} else {
|
||||
return index
|
||||
}
|
||||
})
|
||||
}, [data])
|
||||
|
||||
const previousImage = useCallback(() => {
|
||||
setActiveIndex(index =>
|
||||
index.media > 0 ? { ...index, media: index.media - 1 } : index
|
||||
)
|
||||
})
|
||||
|
||||
const setOnlyFavorites = useCallback(
|
||||
onlyWithFavorites => {
|
||||
history.replaceState(
|
||||
{},
|
||||
'',
|
||||
'/photos' + (onlyWithFavorites ? '/favorites' : '')
|
||||
)
|
||||
|
||||
if (
|
||||
(refetchNeeded.current.all && !onlyWithFavorites) ||
|
||||
(refetchNeeded.current.favorites && onlyWithFavorites)
|
||||
) {
|
||||
refetch({ onlyWithFavorites: onlyWithFavorites }).then(() => {
|
||||
if (onlyWithFavorites) {
|
||||
refetchNeeded.current.favorites = false
|
||||
} else {
|
||||
refetchNeeded.current.all = false
|
||||
}
|
||||
setOnlyWithFavorites(onlyWithFavorites)
|
||||
})
|
||||
} else {
|
||||
setOnlyWithFavorites(onlyWithFavorites)
|
||||
}
|
||||
},
|
||||
[setOnlyWithFavorites]
|
||||
)
|
||||
|
||||
if (error) return error
|
||||
let galleryGroups = []
|
||||
|
||||
if (!loading && data.myAlbums && authToken()) {
|
||||
galleryGroups = data.myAlbums.map((album, index) => (
|
||||
<div key={album.id}>
|
||||
<AlbumTitle album={album} />
|
||||
<PhotoGallery
|
||||
onSelectImage={mediaIndex => {
|
||||
setActiveIndex({ album: index, media: mediaIndex })
|
||||
}}
|
||||
onFavorite={() => {
|
||||
refetchNeeded.current.all = true
|
||||
refetchNeeded.current.favorites = true
|
||||
}}
|
||||
activeIndex={activeIndex.album === index ? activeIndex.media : -1}
|
||||
presenting={presenting === index}
|
||||
setPresenting={presenting =>
|
||||
setPresenting(presenting ? index : false)
|
||||
}
|
||||
loading={loading}
|
||||
media={album.media}
|
||||
nextImage={nextImage}
|
||||
previousImage={previousImage}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<AlbumFilter
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
setOrdering={setOrdering}
|
||||
/>
|
||||
{galleryGroups}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
GalleryGroups.propTypes = {
|
||||
subPage: PropTypes.string,
|
||||
}
|
||||
|
||||
export default GalleryGroups
|
Loading…
Reference in New Issue