- To keep things simple and follow the single-responsibility principle, I decided to move the logic for favorites checkbox and sorting dropdown to a new component instead of adding non-relevant functionality to AlbumTitle. - Added sorting dropdown
This commit is contained in:
parent
53b323640f
commit
9a5127b7a4
|
@ -6,7 +6,12 @@ import AlbumGallery from '../../components/albumGallery/AlbumGallery'
|
|||
import PropTypes from 'prop-types'
|
||||
|
||||
const albumQuery = gql`
|
||||
query albumQuery($id: Int!, $onlyFavorites: Boolean) {
|
||||
query albumQuery(
|
||||
$id: Int!
|
||||
$onlyFavorites: Boolean
|
||||
$mediaOrderBy: String
|
||||
$mediaOrderDirection: OrderDirection
|
||||
) {
|
||||
album(id: $id) {
|
||||
id
|
||||
title
|
||||
|
@ -20,7 +25,10 @@ const albumQuery = gql`
|
|||
}
|
||||
}
|
||||
media(
|
||||
filter: { order_by: "title", order_direction: DESC }
|
||||
filter: {
|
||||
order_by: $mediaOrderBy
|
||||
order_direction: $mediaOrderDirection
|
||||
}
|
||||
onlyFavorites: $onlyFavorites
|
||||
) {
|
||||
id
|
||||
|
@ -51,6 +59,24 @@ 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 toggleFavorites = useCallback(
|
||||
refetch => {
|
||||
const newState = !onlyFavorites
|
||||
|
@ -79,7 +105,15 @@ function AlbumPage({ match }) {
|
|||
)
|
||||
|
||||
return (
|
||||
<Query query={albumQuery} variables={{ id: albumId, onlyFavorites }}>
|
||||
<Query
|
||||
query={albumQuery}
|
||||
variables={{
|
||||
id: albumId,
|
||||
onlyFavorites,
|
||||
mediaOrderBy: orderBy,
|
||||
mediaOrderDirection: orderDirection,
|
||||
}}
|
||||
>
|
||||
{({ loading, error, data, refetch }) => {
|
||||
if (error) return <div>Error</div>
|
||||
return (
|
||||
|
@ -94,6 +128,8 @@ function AlbumPage({ match }) {
|
|||
onFavorite={() =>
|
||||
(refetchNeededAll = refetchNeededFavorites = true)
|
||||
}
|
||||
showFilter
|
||||
setSorting={(e, d) => setSorting(d, refetch)}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -4,13 +4,16 @@ import gql from 'graphql-tag'
|
|||
import { useQuery } from 'react-apollo'
|
||||
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
|
||||
import AlbumTitle from '../../components/AlbumTitle'
|
||||
import { Checkbox } from 'semantic-ui-react'
|
||||
import styled from 'styled-components'
|
||||
import { authToken } from '../../authentication'
|
||||
import PropTypes from 'prop-types'
|
||||
import AlbumFilter from '../../components/AlbumFilter'
|
||||
|
||||
const photoQuery = gql`
|
||||
query allPhotosPage($onlyWithFavorites: Boolean) {
|
||||
query allPhotosPage(
|
||||
$onlyWithFavorites: Boolean
|
||||
$mediaOrderBy: String
|
||||
$mediaOrderDirection: OrderDirection
|
||||
) {
|
||||
myAlbums(
|
||||
filter: { order_by: "title", order_direction: ASC, limit: 100 }
|
||||
onlyWithFavorites: $onlyWithFavorites
|
||||
|
@ -18,7 +21,11 @@ const photoQuery = gql`
|
|||
title
|
||||
id
|
||||
media(
|
||||
filter: { order_by: "media.title", order_direction: DESC, limit: 12 }
|
||||
filter: {
|
||||
order_by: $mediaOrderBy
|
||||
order_direction: $mediaOrderDirection
|
||||
limit: 12
|
||||
}
|
||||
onlyFavorites: $onlyWithFavorites
|
||||
) {
|
||||
id
|
||||
|
@ -43,10 +50,6 @@ const photoQuery = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const FavoritesCheckbox = styled(Checkbox)`
|
||||
margin: 0.5rem 0 0 0;
|
||||
`
|
||||
|
||||
const PhotosPage = ({ match }) => {
|
||||
const [activeIndex, setActiveIndex] = useState({ album: -1, media: -1 })
|
||||
const [presenting, setPresenting] = useState(false)
|
||||
|
@ -56,10 +59,31 @@ const PhotosPage = ({ match }) => {
|
|||
|
||||
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 },
|
||||
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
|
||||
|
@ -81,7 +105,7 @@ const PhotosPage = ({ match }) => {
|
|||
)
|
||||
})
|
||||
|
||||
const favoritesCheckboxClick = useCallback(() => {
|
||||
const setOnlyFavorites = useCallback(() => {
|
||||
const updatedWithFavorites = !onlyWithFavorites
|
||||
|
||||
history.replaceState(
|
||||
|
@ -139,18 +163,16 @@ const PhotosPage = ({ match }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<Layout title="Photos">
|
||||
<FavoritesCheckbox
|
||||
toggle
|
||||
label="Show only favorites"
|
||||
onClick={e => e.stopPropagation()}
|
||||
checked={onlyWithFavorites}
|
||||
onChange={() => {
|
||||
favoritesCheckboxClick()
|
||||
}}
|
||||
/>
|
||||
{galleryGroups}
|
||||
</Layout>
|
||||
<>
|
||||
<Layout title="Photos">
|
||||
<AlbumFilter
|
||||
onlyFavorites={onlyWithFavorites}
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
setSorting={setSorting}
|
||||
/>
|
||||
{galleryGroups}
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import { authToken } from '../authentication'
|
||||
import { Checkbox, Dropdown } from 'semantic-ui-react'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
const sortingOptions = [
|
||||
{
|
||||
key: 'date_shot.ASC',
|
||||
value: 'date_shot.ASC',
|
||||
text: 'Date shot ↑',
|
||||
},
|
||||
{
|
||||
key: 'date_shot.DESC',
|
||||
value: 'date_shot.DESC',
|
||||
text: 'Date shot ↓',
|
||||
},
|
||||
{
|
||||
key: 'date_imported.ASC',
|
||||
value: 'date_imported.ASC',
|
||||
text: 'Date imported ↑',
|
||||
},
|
||||
{
|
||||
key: 'date_imported.DESC',
|
||||
value: 'date_imported.DESC',
|
||||
text: 'Date imported ↓',
|
||||
},
|
||||
{
|
||||
key: 'title.ASC',
|
||||
value: 'title.ASC',
|
||||
text: 'Title ↑',
|
||||
},
|
||||
{
|
||||
key: 'title.DESC',
|
||||
value: 'title.DESC',
|
||||
text: 'Title ↓',
|
||||
},
|
||||
{
|
||||
key: 'kind.ASC',
|
||||
value: 'kind.ASC',
|
||||
text: 'Kind ↑',
|
||||
},
|
||||
{
|
||||
key: 'kind.DESC',
|
||||
value: 'kind.DESC',
|
||||
text: 'Kind ↓',
|
||||
},
|
||||
]
|
||||
|
||||
const FavoritesCheckbox = styled(Checkbox)`
|
||||
margin-bottom: 16px;
|
||||
margin-right: 10px;
|
||||
`
|
||||
|
||||
const AlbumFilter = ({ onlyFavorites, setOnlyFavorites, setSorting }) => {
|
||||
return (
|
||||
<>
|
||||
{authToken() && (
|
||||
<FavoritesCheckbox
|
||||
toggle
|
||||
label="Show only favorites"
|
||||
checked={onlyFavorites}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={setOnlyFavorites}
|
||||
/>
|
||||
)}
|
||||
<strong> Sort by: </strong>
|
||||
<Dropdown
|
||||
options={sortingOptions}
|
||||
defaultValue={sortingOptions[0].value}
|
||||
onChange={setSorting}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
AlbumFilter.propTypes = {
|
||||
onlyFavorites: PropTypes.bool,
|
||||
setOnlyFavorites: PropTypes.func,
|
||||
setSorting: PropTypes.func,
|
||||
}
|
||||
|
||||
export default React.memo(AlbumFilter)
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useContext } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Breadcrumb, Checkbox } from 'semantic-ui-react'
|
||||
import { Breadcrumb } from 'semantic-ui-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import { Icon } from 'semantic-ui-react'
|
||||
|
@ -33,10 +33,6 @@ const StyledIcon = styled(Icon)`
|
|||
}
|
||||
`
|
||||
|
||||
const FavoritesCheckbox = styled(Checkbox)`
|
||||
margin-bottom: 16px;
|
||||
`
|
||||
|
||||
const SettingsIcon = props => {
|
||||
return <StyledIcon name="settings" size="small" {...props} />
|
||||
}
|
||||
|
@ -53,13 +49,7 @@ const ALBUM_PATH_QUERY = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const AlbumTitle = ({
|
||||
album,
|
||||
disableLink = false,
|
||||
showFavoritesToggle,
|
||||
setOnlyFavorites,
|
||||
onlyFavorites = false,
|
||||
}) => {
|
||||
const AlbumTitle = ({ album, disableLink = false }) => {
|
||||
const [fetchPath, { data: pathData }] = useLazyQuery(ALBUM_PATH_QUERY)
|
||||
const { updateSidebar } = useContext(SidebarContext)
|
||||
|
||||
|
@ -113,15 +103,6 @@ const AlbumTitle = ({
|
|||
/>
|
||||
)}
|
||||
</Header>
|
||||
{authToken() && showFavoritesToggle && (
|
||||
<FavoritesCheckbox
|
||||
toggle
|
||||
label="Show only favorites"
|
||||
checked={onlyFavorites}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={setOnlyFavorites}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -129,9 +110,6 @@ const AlbumTitle = ({
|
|||
AlbumTitle.propTypes = {
|
||||
album: PropTypes.object,
|
||||
disableLink: PropTypes.bool,
|
||||
showFavoritesToggle: PropTypes.bool,
|
||||
setOnlyFavorites: PropTypes.func,
|
||||
onlyFavorites: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default AlbumTitle
|
||||
|
|
|
@ -4,13 +4,15 @@ import Layout from '../../Layout'
|
|||
import AlbumTitle from '../AlbumTitle'
|
||||
import PhotoGallery from '../photoGallery/PhotoGallery'
|
||||
import AlbumBoxes from './AlbumBoxes'
|
||||
import AlbumFilter from '../AlbumFilter'
|
||||
|
||||
const AlbumGallery = ({
|
||||
album,
|
||||
loading = false,
|
||||
customAlbumLink,
|
||||
showFavoritesToggle = false,
|
||||
showFilter = false,
|
||||
setOnlyFavorites,
|
||||
setSorting,
|
||||
onlyFavorites = false,
|
||||
onFavorite,
|
||||
}) => {
|
||||
|
@ -86,13 +88,14 @@ const AlbumGallery = ({
|
|||
|
||||
return (
|
||||
<Layout title={album ? album.title : 'Loading album'}>
|
||||
<AlbumTitle
|
||||
album={album}
|
||||
disableLink
|
||||
showFavoritesToggle={showFavoritesToggle}
|
||||
onlyFavorites={onlyFavorites}
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
/>
|
||||
<AlbumTitle album={album} disableLink />
|
||||
{showFilter && (
|
||||
<AlbumFilter
|
||||
onlyFavorites={onlyFavorites}
|
||||
setOnlyFavorites={setOnlyFavorites}
|
||||
setSorting={setSorting}
|
||||
/>
|
||||
)}
|
||||
{subAlbumElement}
|
||||
{
|
||||
<h2
|
||||
|
@ -125,10 +128,11 @@ AlbumGallery.propTypes = {
|
|||
album: PropTypes.object,
|
||||
loading: PropTypes.bool,
|
||||
customAlbumLink: PropTypes.func,
|
||||
showFavoritesToggle: PropTypes.bool,
|
||||
showFilter: PropTypes.bool,
|
||||
setOnlyFavorites: PropTypes.func,
|
||||
onlyFavorites: PropTypes.bool,
|
||||
onFavorite: PropTypes.func,
|
||||
setSorting: PropTypes.func,
|
||||
}
|
||||
|
||||
export default AlbumGallery
|
||||
|
|
Loading…
Reference in New Issue