Skip to content

Commit

Permalink
Dashboard: Single file mode (#4188)
Browse files Browse the repository at this point in the history
* progress pause/resume should be white

* add uppy-c-btn to remaining buttons

* Single file mode: large preview thumbnail for single file

* tweak icon and FileItem sizes

* check for single file mode when files are added or removed

* Don't shorted file names in single file mode

* Refactor a bit

* remove events on uninstall
  • Loading branch information
arturi committed Nov 10, 2022
1 parent 0c4b83c commit a2a265a
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 30 deletions.
24 changes: 24 additions & 0 deletions packages/@uppy/dashboard/src/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,24 @@ export default class Dashboard extends UIPlugin {
this.uppy.emit('restore-canceled')
}

#generateLargeThumbnailIfSingleFile = () => {
if (this.opts.disableThumbnailGenerator) {
return
}

const LARGE_THUMBNAIL = 600
const files = this.uppy.getFiles()

if (files.length === 1) {
const thumbnailGenerator = this.uppy.getPlugin(`${this.id}:ThumbnailGenerator`)
thumbnailGenerator?.setOptions({ thumbnailWidth: LARGE_THUMBNAIL })
const fileForThumbnail = { ...files[0], preview: undefined }
thumbnailGenerator.requestThumbnail(fileForThumbnail).then(() => {
thumbnailGenerator?.setOptions({ thumbnailWidth: this.opts.thumbnailWidth })
})
}
}

#openFileEditorWhenFilesAdded = (files) => {
const firstFile = files[0]
if (this.canEditFile(firstFile)) {
Expand Down Expand Up @@ -732,6 +750,9 @@ export default class Dashboard extends UIPlugin {
this.uppy.on('file-editor:complete', this.hideAllPanels)
this.uppy.on('complete', this.handleComplete)

this.uppy.on('files-added', this.#generateLargeThumbnailIfSingleFile)
this.uppy.on('file-removed', this.#generateLargeThumbnailIfSingleFile)

// ___Why fire on capture?
// Because this.ifFocusedOnUppyRecently needs to change before onUpdate() fires.
document.addEventListener('focus', this.recordIfFocusedOnUppyRecently, true)
Expand Down Expand Up @@ -762,6 +783,9 @@ export default class Dashboard extends UIPlugin {
this.uppy.off('file-editor:complete', this.hideAllPanels)
this.uppy.off('complete', this.handleComplete)

this.uppy.off('files-added', this.#generateLargeThumbnailIfSingleFile)
this.uppy.off('file-removed', this.#generateLargeThumbnailIfSingleFile)

document.removeEventListener('focus', this.recordIfFocusedOnUppyRecently)
document.removeEventListener('click', this.recordIfFocusedOnUppyRecently)

Expand Down
4 changes: 4 additions & 0 deletions packages/@uppy/dashboard/src/components/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const HEIGHT_MD = 400

export default function Dashboard (props) {
const noFiles = props.totalFileCount === 0
const singleFile = props.totalFileCount === 1

const isSizeMD = props.containerWidth > WIDTH_MD

const dashboardClassName = classNames({
Expand All @@ -35,6 +37,7 @@ export default function Dashboard (props) {
'uppy-size--height-md': props.containerHeight > HEIGHT_MD,
'uppy-Dashboard--isAddFilesPanelVisible': props.showAddFilesPanel,
'uppy-Dashboard--isInnerWrapVisible': props.areInsidesReadyToBeVisible,
'uppy-Dashboard--singleFile': singleFile,
})

// Important: keep these in sync with the percent width values in `src/components/FileItem/index.scss`.
Expand Down Expand Up @@ -135,6 +138,7 @@ export default function Dashboard (props) {
<FileList
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
singleFile={singleFile}
itemsPerRow={itemsPerRow}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function EditButton ({
) {
return (
<button
className="uppy-u-reset uppy-Dashboard-Item-action uppy-Dashboard-Item-action--edit"
className="uppy-u-reset uppy-c-btn uppy-Dashboard-Item-action uppy-Dashboard-Item-action--edit"
type="button"
aria-label={i18n('editFileWithFilename', { file: file.meta.name })}
title={i18n('editFileWithFilename', { file: file.meta.name })}
Expand Down
31 changes: 16 additions & 15 deletions packages/@uppy/dashboard/src/components/FileItem/Buttons/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@
opacity: 1;
}

.uppy-size--md &,
.uppy-Dashboard--singleFile & {
position: absolute;
top: -8px;
z-index: $zIndex-3;
width: 18px;
height: 18px;
padding: 0;
inset-inline-end: -8px;

&:focus {
border-radius: 50%;
}
}

[data-uppy-theme="dark"] & {
color: $gray-700;
}
Expand All @@ -40,7 +55,7 @@
}

// Only for mobile screens
.uppy-Dashboard:not(.uppy-size--md) {
.uppy-Dashboard:not(.uppy-size--md):not(.uppy-Dashboard--singleFile) {
// Vertically center Edit&Remove buttons on mobile
.uppy-Dashboard-Item-actionWrapper {
display: flex;
Expand Down Expand Up @@ -71,18 +86,4 @@
border-radius: 3px;
}
}
// Remove button is in the top right corner
.uppy-Dashboard-Item-action--remove {
position: absolute;
top: -8px;
z-index: $zIndex-3;
width: 18px;
height: 18px;
padding: 0;
inset-inline-end: -8px;

&:focus {
border-radius: 50%;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const renderFileName = (props) => {
const { author, name } = props.file.meta

function getMaxNameLength () {
if (props.singleFile) {
return 200
}
if (props.containerWidth <= 352) {
return 35
}
Expand Down Expand Up @@ -78,7 +81,7 @@ const ErrorButton = ({ file, onClick }) => {
if (file.error) {
return (
<button
className="uppy-u-reset uppy-Dashboard-Item-errorDetails"
className="uppy-u-reset uppy-c-btn uppy-Dashboard-Item-errorDetails"
aria-label={file.error}
data-microtip-position="bottom"
data-microtip-size="medium"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
.uppy-Dashboard-Item-fileInfo {
padding-inline-end: 5px;

.uppy-Dashboard--singleFile & {
padding-inline-end: 10px;
}

.uppy-size--md.uppy-Dashboard--singleFile & {
padding-inline-end: 15px;
}
}

.uppy-Dashboard-Item-name {
Expand All @@ -15,6 +23,11 @@
[data-uppy-theme="dark"] & {
color: $gray-200;
}

.uppy-size--md.uppy-Dashboard--singleFile & {
font-size: 14px;
line-height: 1.4;
}
}

.uppy-Dashboard-Item-fileName {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function ProgressIndicatorButton (props) {
return (
<div className="uppy-Dashboard-Item-progress">
<button
className="uppy-u-reset uppy-Dashboard-Item-progressIndicator"
className="uppy-u-reset uppy-c-btn uppy-Dashboard-Item-progressIndicator"
type="button"
aria-label={progressIndicatorTitle(props)}
title={progressIndicatorTitle(props)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
width: 38px;
height: 38px;
opacity: 0.9;
color: $white;

.uppy-size--md & {
width: 55px;
Expand Down
1 change: 1 addition & 0 deletions packages/@uppy/dashboard/src/components/FileItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export default class FileItem extends Component {
toggleAddFilesPanel={this.props.toggleAddFilesPanel}
toggleFileCard={this.props.toggleFileCard}
metaFields={this.props.metaFields}
singleFile={this.props.singleFile}
/>
<Buttons
file={file}
Expand Down
29 changes: 26 additions & 3 deletions packages/@uppy/dashboard/src/components/FileItem/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
align-items: center;
padding: 10px;
border-bottom: 1px solid $gray-200;
padding-inline-end: 0;

.uppy-Dashboard:not(.uppy-Dashboard--singleFile) & {
padding-inline-end: 0;
}

[data-uppy-theme="dark"] & {
border-bottom: 1px solid $gray-800;
Expand Down Expand Up @@ -36,12 +39,25 @@
width: calc(25% - #{$rl-margin} - #{$rl-margin});
height: 190px;
margin: 5px $rl-margin;
padding: 0;
}

.uppy-size--xl & {
/* When changing width: also update `itemsPerRow` values in `src/components/Dashboard.js`. */
width: calc(20% - #{$rl-margin} - #{$rl-margin});
height: 210px;
padding: 0;
}

.uppy-Dashboard--singleFile & {
display: block;
width: 100%;
max-width: 400px;
height: auto;
border-bottom: 0;
position: relative;
padding: 0;
margin: 10px;
}
}

Expand Down Expand Up @@ -78,12 +94,13 @@
position: relative;

// @media only mobile
.uppy-Dashboard:not(.uppy-size--md) & {
.uppy-Dashboard:not(.uppy-size--md):not(.uppy-Dashboard--singleFile) & {
flex-grow: 0;
flex-shrink: 0;
width: 50px;
height: 50px;
}

// @media bigger than .md
.uppy-size--md & {
width: 100%;
Expand All @@ -97,6 +114,11 @@
.uppy-size--xl & {
height: 140px;
}

.uppy-Dashboard--singleFile & {
width: 100%;
height: 270px;
}
}

.uppy-Dashboard-Item-fileInfoAndButtons {
Expand All @@ -107,7 +129,8 @@
padding-inline-end: 8px;
padding-inline-start: 12px;

.uppy-size--md & {
.uppy-size--md &,
.uppy-Dashboard--singleFile & {
align-items: flex-start;
width: 100%;
padding: 0;
Expand Down
20 changes: 11 additions & 9 deletions packages/@uppy/dashboard/src/components/FileList.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import classNames from 'classnames'
import { h } from 'preact'
import FileItem from './FileItem/index.jsx'
import VirtualList from './VirtualList.jsx'
Expand All @@ -19,12 +18,6 @@ function chunks (list, size) {
}

export default (props) => {
const noFiles = props.totalFileCount === 0
const dashboardFilesClass = classNames(
'uppy-Dashboard-files',
{ 'uppy-Dashboard-files--noFiles': noFiles },
)

// It's not great that this is hardcoded!
// It's ESPECIALLY not great that this is checking against `itemsPerRow`!
const rowHeight = props.itemsPerRow === 1
Expand Down Expand Up @@ -53,6 +46,7 @@ export default (props) => {
isWide: props.isWide,
metaFields: props.metaFields,
recoveredState: props.recoveredState,
singleFile: props.singleFile,
// callbacks
toggleFileCard: props.toggleFileCard,
handleRequestThumbnail: props.handleRequestThumbnail,
Expand All @@ -72,7 +66,7 @@ export default (props) => {
// The `role="presentation` attribute ensures that the list items are properly
// associated with the `VirtualList` element.
// We use the first file ID as the key—this should not change across scroll rerenders
<div role="presentation" key={row[0]}>
<div class="uppy-Dashboard-filesInner" role="presentation" key={row[0]}>
{row.map((fileID) => (
<FileItem
key={fileID}
Expand All @@ -88,9 +82,17 @@ export default (props) => {
</div>
)

if (props.singleFile) {
return (
<div class="uppy-Dashboard-files">
{renderRow(rows[0])}
</div>
)
}

return (
<VirtualList
class={dashboardFilesClass}
class="uppy-Dashboard-files"
role="list"
data={rows}
renderRow={renderRow}
Expand Down
16 changes: 16 additions & 0 deletions packages/@uppy/dashboard/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,13 @@
}
}

.uppy-Dashboard--singleFile .uppy-Dashboard-filesInner {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}

.uppy-Dashboard-dropFilesHereHint {
position: absolute;
top: 7px;
Expand Down Expand Up @@ -867,12 +874,21 @@ a.uppy-Dashboard-poweredBy {
width: 100%;
height: 100%;
}

.uppy-Dashboard--singleFile & {
width: 90px;
height: 90px;
}
}

.uppy-Dashboard-Item-previewIconWrap {
position: relative;
height: 76px;
max-height: 75%;

.uppy-Dashboard--singleFile & {
height: 176px;
}
}

.uppy-Dashboard-Item-previewIconBg {
Expand Down

0 comments on commit a2a265a

Please sign in to comment.