Quellcode durchsuchen

Add VirtualList to ProviderView (#4566)

* Add VirtualList to ProviderView

* Import correctly from lib

* fixup! Import correctly from lib

* fixup! fixup! Import correctly from lib

* Really do it this time

* Only virtual list for lists

* fixup! Only virtual list for lists

* Fix scroll

* Set hardcoded width/height for img, as recommened

---------

Co-authored-by: Artur Paikin <artur@arturpaikin.com>
Merlijn Vos vor 1 Jahr
Ursprung
Commit
b1fdf8e926

+ 1 - 1
packages/@uppy/dashboard/src/components/FileList.jsx

@@ -1,7 +1,7 @@
 import { h } from 'preact'
 import { useMemo } from 'preact/hooks'
+import VirtualList from '@uppy/utils/lib/VirtualList'
 import FileItem from './FileItem/index.jsx'
-import VirtualList from './VirtualList.jsx'
 
 function chunks (list, size) {
   const chunked = []

+ 105 - 44
packages/@uppy/provider-views/src/Browser.jsx

@@ -2,12 +2,71 @@ import { h } from 'preact'
 
 import classNames from 'classnames'
 import remoteFileObjToLocal from '@uppy/utils/lib/remoteFileObjToLocal'
+import { useMemo } from 'preact/hooks'
+import VirtualList from '@uppy/utils/lib/VirtualList'
 import SearchFilterInput from './SearchFilterInput.jsx'
 import FooterActions from './FooterActions.jsx'
 import Item from './Item/index.jsx'
 
 const VIRTUAL_SHARED_DIR = 'shared-with-me'
 
+function ListItem (props) {
+  const {
+    currentSelection,
+    uppyFiles,
+    viewType,
+    isChecked,
+    toggleCheckbox,
+    recordShiftKeyPress,
+    showTitles,
+    i18n,
+    validateRestrictions,
+    getNextFolder,
+    columns,
+    f,
+  } = props
+
+  if (f.isFolder) {
+    return Item({
+      columns,
+      showTitles,
+      viewType,
+      i18n,
+      id: f.id,
+      title: f.name,
+      getItemIcon: () => f.icon,
+      isChecked: isChecked(f),
+      toggleCheckbox: (event) => toggleCheckbox(event, f),
+      recordShiftKeyPress,
+      type: 'folder',
+      isDisabled: isChecked(f)?.loading,
+      isCheckboxDisabled: f.id === VIRTUAL_SHARED_DIR,
+      handleFolderClick: () => getNextFolder(f),
+    })
+  }
+  const restrictionError = validateRestrictions(remoteFileObjToLocal(f), [
+    ...uppyFiles,
+    ...currentSelection,
+  ])
+
+  return Item({
+    id: f.id,
+    title: f.name,
+    author: f.author,
+    getItemIcon: () => f.icon,
+    isChecked: isChecked(f),
+    toggleCheckbox: (event) => toggleCheckbox(event, f),
+    recordShiftKeyPress,
+    columns,
+    showTitles,
+    viewType,
+    i18n,
+    type: 'file',
+    isDisabled: restrictionError && !isChecked(f),
+    restrictionError,
+  })
+}
+
 function Browser (props) {
   const {
     currentSelection,
@@ -37,10 +96,13 @@ function Browser (props) {
     done,
     columns,
     noResultsLabel,
+    loadAllFiles,
   } = props
 
   const selected = currentSelection.length
 
+  const rows = useMemo(() => [...folders, ...files], [folders, files])
+
   return (
     <div
       className={classNames(
@@ -85,9 +147,34 @@ function Browser (props) {
         }
 
         if (!folders.length && !files.length) {
+          return <div className="uppy-Provider-empty">{noResultsLabel}</div>
+        }
+
+        if (loadAllFiles) {
           return (
-            <div className="uppy-Provider-empty">
-              {noResultsLabel}
+            <div className="uppy-ProviderBrowser-body">
+              <ul className="uppy-ProviderBrowser-list">
+                <VirtualList
+                  data={rows}
+                  renderRow={(f) => (
+                    <ListItem
+                      currentSelection={currentSelection}
+                      uppyFiles={uppyFiles}
+                      viewType={viewType}
+                      isChecked={isChecked}
+                      toggleCheckbox={toggleCheckbox}
+                      recordShiftKeyPress={recordShiftKeyPress}
+                      showTitles={showTitles}
+                      i18n={i18n}
+                      validateRestrictions={validateRestrictions}
+                      getNextFolder={getNextFolder}
+                      columns={columns}
+                      f={f}
+                    />
+                  )}
+                  rowHeight={31}
+                />
+              </ul>
             </div>
           )
         }
@@ -101,48 +188,22 @@ function Browser (props) {
               // making <ul> not focusable for firefox
               tabIndex="-1"
             >
-              {folders.map((folder) => {
-                return Item({
-                  columns,
-                  showTitles,
-                  viewType,
-                  i18n,
-                  id: folder.id,
-                  title: folder.name,
-                  getItemIcon: () => folder.icon,
-                  isChecked: isChecked(folder),
-                  toggleCheckbox: (event) => toggleCheckbox(event, folder),
-                  recordShiftKeyPress,
-                  type: 'folder',
-                  isDisabled: isChecked(folder)?.loading,
-                  isCheckboxDisabled: folder.id === VIRTUAL_SHARED_DIR,
-                  handleFolderClick: () => getNextFolder(folder),
-                })
-              })}
-
-              {files.map((file) => {
-                const restrictionError = validateRestrictions(
-                  remoteFileObjToLocal(file),
-                  [...uppyFiles, ...currentSelection],
-                )
-
-                return Item({
-                  id: file.id,
-                  title: file.name,
-                  author: file.author,
-                  getItemIcon: () => file.icon,
-                  isChecked: isChecked(file),
-                  toggleCheckbox: (event) => toggleCheckbox(event, file),
-                  recordShiftKeyPress,
-                  columns,
-                  showTitles,
-                  viewType,
-                  i18n,
-                  type: 'file',
-                  isDisabled: restrictionError && !isChecked(file),
-                  restrictionError,
-                })
-              })}
+              {rows.map((f) => (
+                <ListItem
+                  currentSelection={currentSelection}
+                  uppyFiles={uppyFiles}
+                  viewType={viewType}
+                  isChecked={isChecked}
+                  toggleCheckbox={toggleCheckbox}
+                  recordShiftKeyPress={recordShiftKeyPress}
+                  showTitles={showTitles}
+                  i18n={i18n}
+                  validateRestrictions={validateRestrictions}
+                  getNextFolder={getNextFolder}
+                  columns={columns}
+                  f={f}
+                />
+              ))}
             </ul>
           </div>
         )

+ 1 - 1
packages/@uppy/provider-views/src/Item/components/ItemIcon.jsx

@@ -38,7 +38,7 @@ export default (props) => {
       return <VideoIcon />
     default: {
       const { alt } = props
-      return <img src={itemIconString} alt={alt} loading="lazy" />
+      return <img src={itemIconString} alt={alt} loading="lazy" width={16} height={16} />
     }
   }
 }

+ 1 - 0
packages/@uppy/provider-views/src/ProviderView/ProviderView.jsx

@@ -474,6 +474,7 @@ export default class ProviderView extends View {
       username: this.username,
       getNextFolder: this.getNextFolder,
       getFolder: this.getFolder,
+      loadAllFiles: this.opts.loadAllFiles,
 
       // For SearchFilterInput component
       showSearchFilter: targetViewOptions.showFilter,

+ 0 - 2
packages/@uppy/provider-views/src/style/uppy-ProviderBrowser-viewType--list.scss

@@ -83,8 +83,6 @@
 
     img,
     svg {
-      max-width: 20px;
-      max-height: 20px;
       margin-inline-end: 8px;
     }
 

+ 3 - 1
packages/@uppy/utils/package.json

@@ -64,10 +64,12 @@
     "./lib/getDroppedFiles": "./lib/getDroppedFiles/index.js",
     "./lib/FOCUSABLE_ELEMENTS.js": "./lib/FOCUSABLE_ELEMENTS.js",
     "./lib/fileFilters": "./lib/fileFilters.js",
+    "./lib/VirtualList": "./lib/VirtualList.js",
     "./src/microtip.scss": "./src/microtip.scss"
   },
   "dependencies": {
-    "lodash": "^4.17.21"
+    "lodash": "^4.17.21",
+    "preact": "^10.16.0"
   },
   "devDependencies": {
     "@jest/globals": "^29.0.0"

+ 0 - 0
packages/@uppy/dashboard/src/components/VirtualList.jsx → packages/@uppy/utils/src/VirtualList.jsx


+ 1 - 0
yarn.lock

@@ -11592,6 +11592,7 @@ __metadata:
   dependencies:
     "@jest/globals": ^29.0.0
     lodash: ^4.17.21
+    preact: ^10.16.0
   languageName: unknown
   linkType: soft