1
Fork 0
- Performance optimizations - restructured the code so no necessary Layout and AlbumFilter component rerenderings are made.
This commit is contained in:
stz184 2020-10-15 13:48:41 +03:00
parent a290392894
commit 55885ddb65
5 changed files with 195 additions and 204 deletions

View File

@ -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}
/>
)
}}

View File

@ -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>
</>
)

View File

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

View File

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

View File

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