1
Fork 0
- Fixed incorrect typename of the optimistic response of markFavorite()
- Added onFavorite callback to track when media is favorited
- Added logic to refetch the query when media is added/removed to favorites
This commit is contained in:
stz184 2020-09-25 19:10:32 +03:00
parent 23d9d27764
commit 9212ac52eb
6 changed files with 76 additions and 39 deletions

View File

@ -42,49 +42,55 @@ const albumQuery = gql`
} }
` `
let refetchNeededAll = false
let refetchNeededFavorites = false
function AlbumPage({ match }) { function AlbumPage({ match }) {
const albumId = match.params.id const albumId = match.params.id
const showFavorites = match.params.subPage === 'favorites' const [onlyFavorites, setOnlyFavorites] = useState(
match.params.subPage === 'favorites'
const [onlyFavorites, setOnlyFavorites] = useState(showFavorites)
const toggleFavorites = onlyFavorites => {
setOnlyFavorites(onlyFavorites)
if (onlyFavorites) {
history.pushState(
{ showFavorites: onlyFavorites },
'',
'/album/' + albumId + '/favorites'
) )
const toggleFavorites = refetch => {
const onlyFavorites = !onlyFavorites
if (
(refetchNeededAll && !onlyFavorites) ||
(refetchNeededFavorites && onlyFavorites)
) {
refetch({ id: albumId, onlyFavorites: onlyFavorites }).then(() => {
if (onlyFavorites) {
refetchNeededFavorites = false
} else { } else {
history.back() refetchNeededAll = false
} }
setOnlyFavorites(onlyFavorites)
})
} else {
setOnlyFavorites(onlyFavorites)
} }
history.replaceState(
useEffect(() => { {},
const updateImageState = event => { '',
setOnlyFavorites(event.state.showFavorites) '/album/' + albumId + (onlyFavorites ? '/favorites' : '')
)
} }
window.addEventListener('popstate', updateImageState)
return () => {
window.removeEventListener('popstate', updateImageState)
}
}, [setOnlyFavorites])
return ( return (
<Query query={albumQuery} variables={{ id: albumId, onlyFavorites }}> <Query query={albumQuery} variables={{ id: albumId, onlyFavorites }}>
{({ loading, error, data }) => { {({ loading, error, data, refetch }) => {
if (error) return <div>Error</div> if (error) return <div>Error</div>
return ( return (
<AlbumGallery <AlbumGallery
album={data && data.album} album={data && data.album}
loading={loading} loading={loading}
showFavoritesToggle showFavoritesToggle
setOnlyFavorites={toggleFavorites} setOnlyFavorites={() => {
toggleFavorites(refetch)
}}
onlyFavorites={onlyFavorites} onlyFavorites={onlyFavorites}
onFavorite={() =>
(refetchNeededAll = refetchNeededFavorites = true)
}
/> />
) )
}} }}

View File

@ -64,6 +64,8 @@ class PhotosPage extends Component {
this.previousImage = this.previousImage.bind(this) this.previousImage = this.previousImage.bind(this)
this.albums = [] this.albums = []
this.refetchNeededFavorites = false
this.refetchNeededAll = false
} }
onPopState(event) { onPopState(event) {
@ -80,17 +82,33 @@ class PhotosPage extends Component {
window.removeEventListener('popstate', this.onPopState) window.removeEventListener('popstate', this.onPopState)
} }
favoritesCheckboxClick() { favoritesCheckboxClick(refetch) {
const onlyWithFavorites = !this.state.onlyWithFavorites const onlyWithFavorites = !this.state.onlyWithFavorites
history.pushState( history.pushState(
{ showFavorites: onlyWithFavorites }, {},
'', '',
'/photos' + (onlyWithFavorites ? '/favorites' : '') '/photos' + (onlyWithFavorites ? '/favorites' : '')
) )
if (
(this.refetchNeededAll && !onlyWithFavorites) ||
(this.refetchNeededFavorites && onlyWithFavorites)
) {
refetch({ onlyWithFavorites }).then(() => {
if (onlyWithFavorites) {
this.refetchNeededFavorites = false
} else {
this.refetchNeededAll = false
}
this.setState({ this.setState({
onlyWithFavorites, onlyWithFavorites,
}) })
})
} else {
this.setState({
onlyWithFavorites,
})
}
} }
setActiveImage(album, photo) { setActiveImage(album, photo) {
@ -139,7 +157,7 @@ class PhotosPage extends Component {
query={photoQuery} query={photoQuery}
variables={{ onlyWithFavorites: showOnlyWithFavorites }} variables={{ onlyWithFavorites: showOnlyWithFavorites }}
> >
{({ loading, error, data }) => { {({ loading, error, data, refetch }) => {
if (error) return error if (error) return error
if (loading) return null if (loading) return null
@ -157,7 +175,7 @@ class PhotosPage extends Component {
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
checked={showOnlyWithFavorites} checked={showOnlyWithFavorites}
onChange={() => { onChange={() => {
this.favoritesCheckboxClick() this.favoritesCheckboxClick(refetch)
}} }}
/> />
) )
@ -168,6 +186,10 @@ class PhotosPage extends Component {
onSelectImage={photoIndex => { onSelectImage={photoIndex => {
this.setActiveImage(index, photoIndex) this.setActiveImage(index, photoIndex)
}} }}
onFavorite={() => {
this.refetchNeededAll = true
this.refetchNeededFavorites = true
}}
activeIndex={ activeIndex={
this.state.activeAlbumIndex == index this.state.activeAlbumIndex == index
? this.state.activePhotoIndex ? this.state.activePhotoIndex

View File

@ -119,7 +119,7 @@ const AlbumTitle = ({
label="Show only the favorites" label="Show only the favorites"
checked={onlyFavorites} checked={onlyFavorites}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
onChange={() => setOnlyFavorites(!onlyFavorites)} onChange={setOnlyFavorites}
/> />
)} )}
</Header> </Header>

View File

@ -12,6 +12,7 @@ const AlbumGallery = ({
showFavoritesToggle = false, showFavoritesToggle = false,
setOnlyFavorites, setOnlyFavorites,
onlyFavorites = false, onlyFavorites = false,
onFavorite,
}) => { }) => {
const [imageState, setImageState] = useState({ const [imageState, setImageState] = useState({
activeImage: -1, activeImage: -1,
@ -111,6 +112,7 @@ const AlbumGallery = ({
onSelectImage={index => { onSelectImage={index => {
setActiveImage(index) setActiveImage(index)
}} }}
onFavorite={onFavorite}
setPresenting={setPresentingWithHistory} setPresenting={setPresentingWithHistory}
nextImage={nextImage} nextImage={nextImage}
previousImage={previousImage} previousImage={previousImage}
@ -126,6 +128,7 @@ AlbumGallery.propTypes = {
showFavoritesToggle: PropTypes.bool, showFavoritesToggle: PropTypes.bool,
setOnlyFavorites: PropTypes.func, setOnlyFavorites: PropTypes.func,
onlyFavorites: PropTypes.bool, onlyFavorites: PropTypes.bool,
onFavorite: PropTypes.func,
} }
export default AlbumGallery export default AlbumGallery

View File

@ -130,6 +130,7 @@ export const MediaThumbnail = ({
index, index,
active, active,
setPresenting, setPresenting,
onFavorite,
}) => { }) => {
const [markFavorite] = useMutation(markFavoriteMutation) const [markFavorite] = useMutation(markFavoriteMutation)
@ -141,19 +142,21 @@ export const MediaThumbnail = ({
name={media.favorite ? 'heart' : 'heart outline'} name={media.favorite ? 'heart' : 'heart outline'}
onClick={event => { onClick={event => {
event.stopPropagation() event.stopPropagation()
const favorite = !media.favorite
markFavorite({ markFavorite({
variables: { variables: {
mediaId: media.id, mediaId: media.id,
favorite: !media.favorite, favorite: favorite,
}, },
optimisticResponse: { optimisticResponse: {
favoritePhoto: { favoriteMedia: {
id: media.id, id: media.id,
favorite: !media.favorite, favorite: favorite,
__typename: 'Photo', __typename: 'Media',
}, },
}, },
}) })
onFavorite()
}} }}
/> />
) )

View File

@ -40,6 +40,7 @@ const PhotoGallery = ({
setPresenting, setPresenting,
nextImage, nextImage,
previousImage, previousImage,
onFavorite,
}) => { }) => {
const { updateSidebar } = useContext(SidebarContext) const { updateSidebar } = useContext(SidebarContext)
@ -94,6 +95,7 @@ const PhotoGallery = ({
updateSidebar(<MediaSidebar media={photo} />) updateSidebar(<MediaSidebar media={photo} />)
onSelectImage(index) onSelectImage(index)
}} }}
onFavorite={onFavorite}
setPresenting={setPresenting} setPresenting={setPresenting}
minWidth={minWidth} minWidth={minWidth}
index={index} index={index}
@ -140,6 +142,7 @@ PhotoGallery.propTypes = {
setPresenting: PropTypes.func, setPresenting: PropTypes.func,
nextImage: PropTypes.func, nextImage: PropTypes.func,
previousImage: PropTypes.func, previousImage: PropTypes.func,
onFavorite: PropTypes.func,
} }
export default PhotoGallery export default PhotoGallery