From 334866b2a94289dbd89354893987b395cbcb13af Mon Sep 17 00:00:00 2001 From: Yannick Lohse Date: Wed, 11 Apr 2018 18:11:37 +0200 Subject: [PATCH] feat: file list placeholder navigation animation --- src/drive/components/FileListPlaceholder.jsx | 93 ++++++++++++++++++++ src/drive/components/FolderContent.jsx | 59 ++++++++----- src/drive/components/FolderView.jsx | 2 + src/drive/components/LightFolderView.jsx | 2 + src/drive/styles/foldercontent.styl | 5 -- src/drive/styles/table.styl | 54 +++++++++--- 6 files changed, 175 insertions(+), 40 deletions(-) create mode 100644 src/drive/components/FileListPlaceholder.jsx delete mode 100644 src/drive/styles/foldercontent.styl diff --git a/src/drive/components/FileListPlaceholder.jsx b/src/drive/components/FileListPlaceholder.jsx new file mode 100644 index 0000000000..2f76d69d6d --- /dev/null +++ b/src/drive/components/FileListPlaceholder.jsx @@ -0,0 +1,93 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classNames from 'classnames' +import styles from '../styles/table' + +// using a seeded PRNG to prevent re-renders from changing the results +const seededRandom = seed => { + const x = Math.sin(seed) * 10000 + return x - Math.floor(x) +} +const seededRandomBetween = (min, max, seed) => + min + seededRandom(seed) * (max - min) + +const PlaceholderBlock = ({ width }) => ( +
+) + +PlaceholderBlock.propTypes = { + width: PropTypes.string +} + +PlaceholderBlock.defaultProps = { + width: '100%' +} + +const FilePlaceholder = ({ index }) => ( +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+) + +FilePlaceholder.propTypes = { + index: PropTypes.number +} + +FilePlaceholder.defaultProps = { + index: 1 +} + +const FileListPlaceholder = ({ rows }) => ( +
+ {[...new Array(rows)].map((value, index) => ( + + ))} +
+) + +FileListPlaceholder.propTypes = { + rows: PropTypes.number +} + +FileListPlaceholder.defaultProps = { + rows: 8 +} + +export default FileListPlaceholder diff --git a/src/drive/components/FolderContent.jsx b/src/drive/components/FolderContent.jsx index ab97f9e8ed..0ffc9815dc 100644 --- a/src/drive/components/FolderContent.jsx +++ b/src/drive/components/FolderContent.jsx @@ -1,9 +1,9 @@ import React from 'react' -import Spinner from 'cozy-ui/react/Spinner' +import PropTypes from 'prop-types' import Oops from 'components/Error/Oops' import { EmptyDrive, EmptyTrash } from 'components/Error/Empty' +import FileListPlaceholder from './FileListPlaceholder' import FileList from './FileList' -import styles from '../styles/foldercontent' const EmptyContent = props => { const { isTrashContext, canUpload } = props @@ -13,29 +13,40 @@ const EmptyContent = props => { return } +EmptyContent.propTypes = { + isTrashContext: PropTypes.bool, + canUpload: PropTypes.bool, + params: PropTypes.object +} + +EmptyContent.defaultProps = { + isTrashContext: false, + canUpload: false, + params: {} +} + const FolderContent = props => { - const { fetchStatus, files, isAddingFolder } = props - switch (fetchStatus) { - case 'pending': - return ( - - ) - case 'failed': - return - case 'loaded': - return files.length === 0 && !isAddingFolder ? ( - - ) : ( - - ) - default: - return null - } + const { files, isAddingFolder, isLoading, isInError } = props + + if (isLoading) return + else if (isInError) return + else if (files.length === 0 && !isAddingFolder) + return + else return +} + +FolderContent.propTypes = { + files: PropTypes.array, + isAddingFolder: PropTypes.bool, + isLoading: PropTypes.bool, + isInError: PropTypes.bool +} + +FolderContent.defaultProps = { + files: [], + isAddingFolder: false, + isLoading: false, + isInError: false } export default FolderContent diff --git a/src/drive/components/FolderView.jsx b/src/drive/components/FolderView.jsx index 209f4c80e6..3228864a9d 100644 --- a/src/drive/components/FolderView.jsx +++ b/src/drive/components/FolderView.jsx @@ -111,6 +111,8 @@ class FolderView extends Component { {...this.props} selectionModeActive={selectionModeActive} isAddingFolder={showAddFolder} + isLoading={fetchPending || isNavigating} + isInError={fetchFailed} />
diff --git a/src/drive/components/LightFolderView.jsx b/src/drive/components/LightFolderView.jsx index 9ffcc1ef67..e419945bdb 100644 --- a/src/drive/components/LightFolderView.jsx +++ b/src/drive/components/LightFolderView.jsx @@ -115,6 +115,8 @@ class DumbFolderView extends React.Component { {viewerOpened && ( diff --git a/src/drive/styles/foldercontent.styl b/src/drive/styles/foldercontent.styl deleted file mode 100644 index 18acbef6e7..0000000000 --- a/src/drive/styles/foldercontent.styl +++ /dev/null @@ -1,5 +0,0 @@ -@require 'settings/breakpoints.styl' - -+medium-screen() - .content-spinner - position fixed diff --git a/src/drive/styles/table.styl b/src/drive/styles/table.styl index b7abc20ff4..d0e85f5486 100644 --- a/src/drive/styles/table.styl +++ b/src/drive/styles/table.styl @@ -161,25 +161,57 @@ mime-types('fil-file-', '../assets/icons/') @keyframes placeHolderShimmer 0% - background-position -29.25rem 0 + background-position -20rem 0 + 80% + background-position 20rem 0 + 80.1% + background-position -20rem 0 100% - background-position 29.25rem 0 + background-position -20rem 0 .fil-content-file-placeholder - animation-duration 1s - animation-fill-mode forwards + animation-duration 2s animation-iteration-count infinite animation-name placeHolderShimmer animation-timing-function linear - border-radius .1875rem - background #f6f7f8 - background #eeeeee - background linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%) - background-size 50rem 6.5rem - height 1.25rem - width 67% + background-position -20rem 0 + background-image linear-gradient(to right, paleGrey 0%, #FCFCFC 50%, paleGrey 100%) + background-size 20rem 2.5rem + background-repeat no-repeat + background-color paleGrey + border-radius .15rem + height .75rem + max-width 100% position relative +.fil-content-file .fil-content-file-placeholder:before + content "" + display inline-block + width 2rem + height 2rem + background inherit + animation inherit + border-radius inherit + position absolute + right 100% + top -80% + margin-right 1rem + +.fil-content-file .fil-content-file-placeholder:before + animation-delay 0s + +.fil-content-file .fil-content-file-placeholder + animation-delay .1s + +.fil-content-date .fil-content-file-placeholder + animation-delay .5s + +.fil-content-size .fil-content-file-placeholder + animation-delay .7s + +.fil-content-status .fil-content-file-placeholder + animation-delay 1.1s + +medium-screen() .fil-content-table-selection .fil-content-body