1
Fork 0

Rewrite PhotosPage with react hooks

This commit is contained in:
viktorstrate 2020-10-01 22:19:40 +02:00
parent 4fe0608194
commit 6e2d5032ee
3 changed files with 88 additions and 140 deletions

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react' import React, { useCallback, useRef, useState } from 'react'
import Layout from '../../Layout' import Layout from '../../Layout'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Query } from 'react-apollo' import { useQuery } from 'react-apollo'
import PhotoGallery from '../../components/photoGallery/PhotoGallery' import PhotoGallery from '../../components/photoGallery/PhotoGallery'
import AlbumTitle from '../../components/AlbumTitle' import AlbumTitle from '../../components/AlbumTitle'
import { Checkbox } from 'semantic-ui-react' import { Checkbox } from 'semantic-ui-react'
@ -47,163 +47,111 @@ const FavoritesCheckbox = styled(Checkbox)`
margin: 0.5rem 0 0 0; margin: 0.5rem 0 0 0;
` `
class PhotosPage extends Component { const PhotosPage = ({ match }) => {
constructor(props) { const [activeIndex, setActiveIndex] = useState({ album: -1, media: -1 })
super(props) const [presenting, setPresenting] = useState(false)
const [onlyWithFavorites, setOnlyWithFavorites] = useState(
match.params.subPage === 'favorites'
)
this.state = { const refetchNeeded = useRef({ all: false, favorites: false })
activeAlbumIndex: -1,
activePhotoIndex: -1,
presenting: false,
onlyWithFavorites: this.props.match.params.subPage === 'favorites',
}
this.setPresenting = this.setPresenting.bind(this) const { loading, error, data, refetch } = useQuery(photoQuery, {
this.nextImage = this.nextImage.bind(this) variables: { onlyWithFavorites: onlyWithFavorites },
this.previousImage = this.previousImage.bind(this) })
this.albums = [] const nextImage = useCallback(() => {
this.refetchNeededFavorites = false setActiveIndex(index => {
this.refetchNeededAll = false 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 favoritesCheckboxClick = useCallback(() => {
const updatedWithFavorites = !onlyWithFavorites
favoritesCheckboxClick(refetch) {
const onlyWithFavorites = !this.state.onlyWithFavorites
history.replaceState( history.replaceState(
{}, {},
'', '',
'/photos' + (onlyWithFavorites ? '/favorites' : '') '/photos' + (updatedWithFavorites ? '/favorites' : '')
) )
if ( if (
(this.refetchNeededAll && !onlyWithFavorites) || (refetchNeeded.current.all && !updatedWithFavorites) ||
(this.refetchNeededFavorites && onlyWithFavorites) (refetchNeeded.current.favorites && updatedWithFavorites)
) { ) {
refetch({ onlyWithFavorites }).then(() => { refetch({ onlyWithFavorites: updatedWithFavorites }).then(() => {
if (onlyWithFavorites) { if (updatedWithFavorites) {
this.refetchNeededFavorites = false refetchNeeded.current.favorites = false
} else { } else {
this.refetchNeededAll = false refetchNeeded.current.all = false
} }
this.setState({ setOnlyWithFavorites(updatedWithFavorites)
onlyWithFavorites,
})
}) })
} else { } else {
this.setState({ setOnlyWithFavorites(updatedWithFavorites)
onlyWithFavorites,
})
} }
} }, [onlyWithFavorites])
setActiveImage(album, photo) { if (error) return error
this.setState({ if (loading) return null
activePhotoIndex: photo,
activeAlbumIndex: album,
})
}
setPresenting(presenting, index) { let galleryGroups = []
if (presenting) {
this.setState({
presenting: index,
})
} else {
this.setState({
presenting: false,
})
}
}
nextImage() { if (data.myAlbums && authToken()) {
const albumImageCount = this.albums[this.state.activeAlbumIndex].media galleryGroups = data.myAlbums.map((album, index) => (
.length <div key={album.id}>
<AlbumTitle album={album} />
if (this.state.activePhotoIndex + 1 < albumImageCount) { <PhotoGallery
this.setState({ onSelectImage={mediaIndex => {
activePhotoIndex: this.state.activePhotoIndex + 1, setActiveIndex({ album: index, media: mediaIndex })
})
}
}
previousImage() {
if (this.state.activePhotoIndex > 0) {
this.setState({
activePhotoIndex: this.state.activePhotoIndex - 1,
})
}
}
render() {
const showOnlyWithFavorites = this.state.onlyWithFavorites
return (
<Layout title="Photos">
<Query
query={photoQuery}
variables={{ onlyWithFavorites: showOnlyWithFavorites }}
>
{({ loading, error, data, refetch }) => {
if (error) return error
if (loading) return null
let galleryGroups = []
let favoritesSwitch = ''
this.albums = data.myAlbums
if (data.myAlbums && authToken()) {
favoritesSwitch = (
<FavoritesCheckbox
toggle
label="Show only the favorites"
onClick={e => e.stopPropagation()}
checked={showOnlyWithFavorites}
onChange={() => {
this.favoritesCheckboxClick(refetch)
}}
/>
)
galleryGroups = data.myAlbums.map((album, index) => (
<div key={album.id}>
<AlbumTitle album={album} />
<PhotoGallery
onSelectImage={photoIndex => {
this.setActiveImage(index, photoIndex)
}}
onFavorite={() => {
this.refetchNeededAll = true
this.refetchNeededFavorites = true
}}
activeIndex={
this.state.activeAlbumIndex == index
? this.state.activePhotoIndex
: -1
}
presenting={this.state.presenting === index}
setPresenting={presenting =>
this.setPresenting(presenting, index)
}
loading={loading}
media={album.media}
nextImage={this.nextImage}
previousImage={this.previousImage}
/>
</div>
))
}
return (
<div>
{favoritesSwitch}
{galleryGroups}
</div>
)
}} }}
</Query> onFavorite={() => {
</Layout> 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">
<FavoritesCheckbox
toggle
label="Show only favorites"
onClick={e => e.stopPropagation()}
checked={onlyWithFavorites}
onChange={() => {
favoritesCheckboxClick()
}}
/>
{galleryGroups}
</Layout>
)
} }
PhotosPage.propTypes = { PhotosPage.propTypes = {

View File

@ -116,7 +116,7 @@ const AlbumTitle = ({
{authToken() && showFavoritesToggle && ( {authToken() && showFavoritesToggle && (
<FavoritesCheckbox <FavoritesCheckbox
toggle toggle
label="Show only the favorites" label="Show only favorites"
checked={onlyFavorites} checked={onlyFavorites}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
onChange={setOnlyFavorites} onChange={setOnlyFavorites}

View File

@ -246,7 +246,7 @@ const SidebarShare = ({ photo, album }) => {
let content = null let content = null
if (!content && sharesError) { if (sharesError) {
content = <div>Error: {sharesError.message}</div> content = <div>Error: {sharesError.message}</div>
} }