1
Fork 0

Improve skeleton loading design

This commit is contained in:
viktorstrate 2020-02-16 17:32:55 +01:00
parent 34729c763f
commit 565eacb725
6 changed files with 76 additions and 24 deletions

View File

@ -8,6 +8,7 @@ import AlbumSidebar from './sidebar/AlbumSidebar'
const Header = styled.h1` const Header = styled.h1`
margin: 0 0 12px 0 !important; margin: 0 0 12px 0 !important;
height: 36px;
& a { & a {
color: black; color: black;
@ -34,7 +35,7 @@ const SettingsIcon = props => {
} }
const AlbumTitle = ({ album, disableLink = false }) => { const AlbumTitle = ({ album, disableLink = false }) => {
if (!album) return null if (!album) return <div style={{ height: 36 }}></div>
let title = <span>{album.title}</span> let title = <span>{album.title}</span>

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { useState } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
@ -12,26 +12,51 @@ const AlbumBoxLink = styled(Link)`
color: #222; color: #222;
` `
const AlbumBoxImage = ({ src, ...props }) => { const ImageWrapper = styled.div`
const Image = styled(ProtectedImage)` width: 240px;
width: 220px; height: 220px;
height: 220px; padding: 0 10px;
margin: auto; position: relative;
border-radius: 4%; `
object-fit: cover;
object-position: center;
`
const Placeholder = styled.div` const Image = styled(ProtectedImage)`
width: 220px; width: 220px;
height: 220px; height: 220px;
border-radius: 4%; margin: auto;
margin: auto; border-radius: 4%;
background: linear-gradient(#f7f7f7 0%, #eee 100%); object-fit: cover;
` object-position: center;
`
const Placeholder = styled.div`
width: 220px;
height: 220px;
border-radius: 4%;
margin: auto;
background: linear-gradient(#f7f7f7 0%, #eee 100%);
${({ overlap, loaded }) =>
overlap &&
`
position: absolute;
top: 0;
left: 10px;
opacity: ${loaded ? 0 : 1};
transition: opacity 200ms;
`}
`
const AlbumBoxImage = ({ src, ...props }) => {
const [loaded, setLoaded] = useState(false)
if (src) { if (src) {
return <Image {...props} src={src} /> return (
<ImageWrapper>
<Image {...props} onLoad={loaded => setLoaded(loaded)} src={src} />
<Placeholder overlap loaded={loaded ? 1 : 0} />
</ImageWrapper>
)
} }
return <Placeholder /> return <Placeholder />

View File

@ -23,14 +23,14 @@ const AlbumBoxes = ({ loading, error, albums, getCustomLink }) => {
/> />
)) ))
} else { } else {
for (let i = 0; i < 8; i++) { for (let i = 0; i < 4; i++) {
albumElements.push(<AlbumBox key={i} />) albumElements.push(<AlbumBox key={i} />)
} }
} }
return ( return (
<Container> <Container>
<Loader active={loading}>Loading albums</Loader> {/* <Loader active={loading}>Loading albums</Loader> */}
{albumElements} {albumElements}
</Container> </Container>
) )

View File

@ -65,13 +65,24 @@ const AlbumGallery = ({ album, loading = false, customAlbumLink }) => {
/> />
) )
} }
} else {
subAlbumElement = <AlbumBoxes loading={loading} />
} }
return ( return (
<Layout> <Layout>
<AlbumTitle album={album} disableLink /> <AlbumTitle album={album} disableLink />
{subAlbumElement} {subAlbumElement}
{album && album.subAlbums.length > 0 && <h2>Images</h2>} {
<h2
style={{
opacity: loading ? 0 : 1,
display: album && album.subAlbums.length > 0 ? 'block' : 'none',
}}
>
Images
</h2>
}
<PhotoGallery <PhotoGallery
loading={loading} loading={loading}
photos={album && album.photos} photos={album && album.photos}

View File

@ -139,3 +139,12 @@ Photo.propTypes = {
active: PropTypes.bool.isRequired, active: PropTypes.bool.isRequired,
setPresenting: PropTypes.func.isRequired, setPresenting: PropTypes.func.isRequired,
} }
export const PhotoThumbnail = styled.div`
flex-grow: 1;
height: 200px;
width: 300px;
margin: 4px;
background-color: #eee;
position: relative;
`

View File

@ -1,7 +1,7 @@
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { Loader } from 'semantic-ui-react' import { Loader } from 'semantic-ui-react'
import { Photo } from './Photo' import { Photo, PhotoThumbnail } from './Photo'
import { PresentContainer, PresentPhoto } from './PresentView' import { PresentContainer, PresentPhoto } from './PresentView'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { SidebarConsumer } from '../sidebar/Sidebar' import { SidebarConsumer } from '../sidebar/Sidebar'
@ -11,6 +11,8 @@ const Gallery = styled.div`
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
min-height: 200px;
position: relative;
` `
const PhotoFiller = styled.div` const PhotoFiller = styled.div`
@ -62,7 +64,7 @@ const PhotoGallery = ({
const activeImage = photos && activeIndex != -1 && photos[activeIndex] const activeImage = photos && activeIndex != -1 && photos[activeIndex]
const getPhotoElements = updateSidebar => { const getPhotoElements = updateSidebar => {
let photoElements = null let photoElements = []
if (photos) { if (photos) {
photos.filter(photo => photo.thumbnail) photos.filter(photo => photo.thumbnail)
@ -91,6 +93,10 @@ const PhotoGallery = ({
/> />
) )
}) })
} else {
for (let i = 0; i < 6; i++) {
photoElements.push(<PhotoThumbnail />)
}
} }
return photoElements return photoElements