浏览代码

Fix provider panel being closed when selecting a directory

`<Browser />` gets unmounted often, for example when clicking a
directory it's temporarily swapped out for a `<LoadingView />`. This
moves the selection clear code to a wrapper component that only unmounts
once the entire panel is closed by the user.
Renée Kooi 7 年之前
父节点
当前提交
4cf195e58a
共有 2 个文件被更改,包括 90 次插入67 次删除
  1. 49 53
      src/views/ProviderView/Browser.js
  2. 41 14
      src/views/ProviderView/index.js

+ 49 - 53
src/views/ProviderView/Browser.js

@@ -3,63 +3,59 @@ const Breadcrumbs = require('./Breadcrumbs')
 const Filter = require('./Filter')
 const Filter = require('./Filter')
 const Table = require('./ItemList')
 const Table = require('./ItemList')
 const FooterActions = require('./FooterActions')
 const FooterActions = require('./FooterActions')
-const { h, Component } = require('preact')
+const { h } = require('preact')
 
 
-module.exports = class Browser extends Component {
-  componentWillUnmount () {
-    this.props.cancel()
-  }
-
-  render (props) {
-    let filteredFolders = props.folders
-    let filteredFiles = props.files
+const Browser = (props) => {
+  let filteredFolders = props.folders
+  let filteredFiles = props.files
 
 
-    if (props.filterInput !== '') {
-      filteredFolders = props.filterItems(props.folders)
-      filteredFiles = props.filterItems(props.files)
-    }
+  if (props.filterInput !== '') {
+    filteredFolders = props.filterItems(props.folders)
+    filteredFiles = props.filterItems(props.files)
+  }
 
 
-    const selected = props.currentSelection.length
+  const selected = props.currentSelection.length
 
 
-    return (
-      <div class={classNames('uppy-ProviderBrowser', `uppy-ProviderBrowser-viewType--${props.viewType}`)}>
-        <div class="uppy-ProviderBrowser-header">
-          <div class={classNames('uppy-ProviderBrowser-headerBar', !props.showBreadcrumbs && 'uppy-ProviderBrowser-headerBar--simple')}>
-            <div class="uppy-Provider-breadcrumbsIcon">{props.pluginIcon && props.pluginIcon()}</div>
-            {props.showBreadcrumbs && <Breadcrumbs
-              getFolder={props.getFolder}
-              directories={props.directories}
-              title={props.title} />
-            }
-            <button type="button" onclick={props.logout} class="uppy-ProviderBrowser-userLogout">
-              {props.i18n('logOut')}
-            </button>
-          </div>
+  return (
+    <div class={classNames('uppy-ProviderBrowser', `uppy-ProviderBrowser-viewType--${props.viewType}`)}>
+      <div class="uppy-ProviderBrowser-header">
+        <div class={classNames('uppy-ProviderBrowser-headerBar', !props.showBreadcrumbs && 'uppy-ProviderBrowser-headerBar--simple')}>
+          <div class="uppy-Provider-breadcrumbsIcon">{props.pluginIcon && props.pluginIcon()}</div>
+          {props.showBreadcrumbs && <Breadcrumbs
+            getFolder={props.getFolder}
+            directories={props.directories}
+            title={props.title} />
+          }
+          <button type="button" onclick={props.logout} class="uppy-ProviderBrowser-userLogout">
+            {props.i18n('logOut')}
+          </button>
         </div>
         </div>
-        { props.showFilter && <Filter {...props} /> }
-        <Table
-          columns={[{
-            name: 'Name',
-            key: 'title'
-          }]}
-          folders={filteredFolders}
-          files={filteredFiles}
-          activeRow={props.isActiveRow}
-          sortByTitle={props.sortByTitle}
-          sortByDate={props.sortByDate}
-          isChecked={props.isChecked}
-          handleFolderClick={props.getNextFolder}
-          toggleCheckbox={props.toggleCheckbox}
-          getItemName={props.getItemName}
-          getItemIcon={props.getItemIcon}
-          handleScroll={props.handleScroll}
-          title={props.title}
-          showTitles={props.showTitles}
-          getItemId={props.getItemId}
-          i18n={props.i18n}
-        />
-        {selected > 0 && <FooterActions selected={selected} {...props} />}
       </div>
       </div>
-    )
-  }
+      { props.showFilter && <Filter {...props} /> }
+      <Table
+        columns={[{
+          name: 'Name',
+          key: 'title'
+        }]}
+        folders={filteredFolders}
+        files={filteredFiles}
+        activeRow={props.isActiveRow}
+        sortByTitle={props.sortByTitle}
+        sortByDate={props.sortByDate}
+        isChecked={props.isChecked}
+        handleFolderClick={props.getNextFolder}
+        toggleCheckbox={props.toggleCheckbox}
+        getItemName={props.getItemName}
+        getItemIcon={props.getItemIcon}
+        handleScroll={props.handleScroll}
+        title={props.title}
+        showTitles={props.showTitles}
+        getItemId={props.getItemId}
+        i18n={props.i18n}
+      />
+      {selected > 0 && <FooterActions selected={selected} {...props} />}
+    </div>
+  )
 }
 }
+
+module.exports = Browser

+ 41 - 14
src/views/ProviderView/index.js

@@ -2,7 +2,7 @@ const AuthView = require('./AuthView')
 const Browser = require('./Browser')
 const Browser = require('./Browser')
 const LoaderView = require('./Loader')
 const LoaderView = require('./Loader')
 const Utils = require('../../core/Utils')
 const Utils = require('../../core/Utils')
-const { h } = require('preact')
+const { h, Component } = require('preact')
 
 
 /**
 /**
  * Array.prototype.findIndex ponyfill for old browsers.
  * Array.prototype.findIndex ponyfill for old browsers.
@@ -14,6 +14,16 @@ function findIndex (array, predicate) {
   return -1
   return -1
 }
 }
 
 
+class CloseWrapper extends Component {
+  componentWillUnmount () {
+    this.props.onUnmount()
+  }
+
+  render () {
+    return this.props.children[0]
+  }
+}
+
 /**
 /**
  * Class to easily generate generic views for plugins
  * Class to easily generate generic views for plugins
  *
  *
@@ -83,11 +93,12 @@ module.exports = class ProviderView {
     this.handleScroll = this.handleScroll.bind(this)
     this.handleScroll = this.handleScroll.bind(this)
     this.donePicking = this.donePicking.bind(this)
     this.donePicking = this.donePicking.bind(this)
     this.cancelPicking = this.cancelPicking.bind(this)
     this.cancelPicking = this.cancelPicking.bind(this)
+    this.clearSelection = this.clearSelection.bind(this)
 
 
     // Visual
     // Visual
     this.render = this.render.bind(this)
     this.render = this.render.bind(this)
 
 
-    this.plugin.setPluginState({ currentSelection: [] })
+    this.clearSelection()
   }
   }
 
 
   tearDown () {
   tearDown () {
@@ -496,7 +507,7 @@ module.exports = class ProviderView {
     })
     })
 
 
     this._loaderWrapper(Promise.all(promises), () => {
     this._loaderWrapper(Promise.all(promises), () => {
-      this.plugin.setPluginState({ currentSelection: [] })
+      this.clearSelection()
 
 
       const dashboard = this.plugin.uppy.getPlugin('Dashboard')
       const dashboard = this.plugin.uppy.getPlugin('Dashboard')
       if (dashboard) dashboard.hideAllPanels()
       if (dashboard) dashboard.hideAllPanels()
@@ -504,12 +515,16 @@ module.exports = class ProviderView {
   }
   }
 
 
   cancelPicking () {
   cancelPicking () {
-    this.plugin.setPluginState({ currentSelection: [] })
+    this.clearSelection()
 
 
     const dashboard = this.plugin.uppy.getPlugin('Dashboard')
     const dashboard = this.plugin.uppy.getPlugin('Dashboard')
     if (dashboard) dashboard.hideAllPanels()
     if (dashboard) dashboard.hideAllPanels()
   }
   }
 
 
+  clearSelection () {
+    this.plugin.setPluginState({ currentSelection: [] })
+  }
+
   // displays loader view while asynchronous request is being made.
   // displays loader view while asynchronous request is being made.
   _loaderWrapper (promise, then, catch_) {
   _loaderWrapper (promise, then, catch_) {
     promise
     promise
@@ -522,18 +537,26 @@ module.exports = class ProviderView {
     const { authenticated, checkAuthInProgress, loading } = this.plugin.getPluginState()
     const { authenticated, checkAuthInProgress, loading } = this.plugin.getPluginState()
 
 
     if (loading) {
     if (loading) {
-      return <LoaderView />
+      return (
+        <CloseWrapper onUnmount={this.clearSelection}>
+          <LoaderView />
+        </CloseWrapper>
+      )
     }
     }
 
 
     if (!authenticated) {
     if (!authenticated) {
-      return <AuthView
-        pluginName={this.plugin.title}
-        pluginIcon={this.plugin.icon}
-        demo={this.plugin.opts.demo}
-        checkAuth={this.checkAuth}
-        handleAuth={this.handleAuth}
-        handleDemoAuth={this.handleDemoAuth}
-        checkAuthInProgress={checkAuthInProgress} />
+      return (
+        <CloseWrapper onUnmount={this.clearSelection}>
+          <AuthView
+            pluginName={this.plugin.title}
+            pluginIcon={this.plugin.icon}
+            demo={this.plugin.opts.demo}
+            checkAuth={this.checkAuth}
+            handleAuth={this.handleAuth}
+            handleDemoAuth={this.handleDemoAuth}
+            checkAuthInProgress={checkAuthInProgress} />
+        </CloseWrapper>
+      )
     }
     }
 
 
     const browserProps = Object.assign({}, this.plugin.getPluginState(), {
     const browserProps = Object.assign({}, this.plugin.getPluginState(), {
@@ -565,6 +588,10 @@ module.exports = class ProviderView {
       i18n: this.plugin.uppy.i18n
       i18n: this.plugin.uppy.i18n
     })
     })
 
 
-    return <Browser {...browserProps} />
+    return (
+      <CloseWrapper onUnmount={this.clearSelection}>
+        <Browser {...browserProps} />
+      </CloseWrapper>
+    )
   }
   }
 }
 }