Skip to content

Commit

Permalink
Create base provider class View
Browse files Browse the repository at this point in the history
  • Loading branch information
Murderlon committed Sep 16, 2021
1 parent fa1f35b commit 2853116
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 214 deletions.
131 changes: 21 additions & 110 deletions packages/@uppy/provider-views/src/ProviderView/ProviderView.js
@@ -1,13 +1,10 @@
const { h } = require('preact')
const generateFileID = require('@uppy/utils/lib/generateFileID')
const getFileType = require('@uppy/utils/lib/getFileType')
const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported')
const AuthView = require('./AuthView')
const Header = require('./Header')
const Browser = require('../Browser')
const LoaderView = require('../Loader')
const SharedHandler = require('../SharedHandler')
const CloseWrapper = require('../CloseWrapper')
const View = require('../View')

function getOrigin () {
// eslint-disable-next-line no-restricted-globals
Expand All @@ -17,22 +14,15 @@ function getOrigin () {
/**
* Class to easily generate generic views for Provider plugins
*/
module.exports = class ProviderView {
module.exports = class ProviderView extends View {
static VERSION = require('../../package.json').version

#isHandlingScroll

#sharedHandler

/**
* @param {object} plugin instance of the plugin
* @param {object} opts
*/
constructor (plugin, opts) {
this.plugin = plugin
this.provider = opts.provider
this.#sharedHandler = new SharedHandler(plugin)

super(plugin, opts)
// set default options
const defaultOptions = {
viewType: 'list',
Expand All @@ -45,25 +35,18 @@ module.exports = class ProviderView {
this.opts = { ...defaultOptions, ...opts }

// Logic
this.addFile = this.addFile.bind(this)
this.filterQuery = this.filterQuery.bind(this)
this.getFolder = this.getFolder.bind(this)
this.getNextFolder = this.getNextFolder.bind(this)
this.logout = this.logout.bind(this)
this.preFirstRender = this.preFirstRender.bind(this)
this.handleAuth = this.handleAuth.bind(this)
this.handleError = this.handleError.bind(this)
this.handleScroll = this.handleScroll.bind(this)
this.listAllFiles = this.listAllFiles.bind(this)
this.donePicking = this.donePicking.bind(this)
this.cancelPicking = this.cancelPicking.bind(this)
this.clearSelection = this.clearSelection.bind(this)

// Visual
this.render = this.render.bind(this)

this.clearSelection()

// Set default state for the plugin
this.plugin.setPluginState({
authenticated: false,
Expand All @@ -72,6 +55,7 @@ module.exports = class ProviderView {
directories: [],
filterInput: '',
isSearchVisible: false,
currentSelection: [],
})
}

Expand All @@ -92,23 +76,14 @@ module.exports = class ProviderView {
this.plugin.setPluginState({ folders, files })
}

/**
* Called only the first time the provider view is rendered.
* Kind of like an init function.
*/
preFirstRender () {
this.plugin.setPluginState({ didFirstRender: true })
this.plugin.onFirstRender()
}

/**
* Based on folder ID, fetch a new folder and update it to state
*
* @param {string} id Folder id
* @returns {Promise} Folders/files in folder
*/
getFolder (id, name) {
return this.#sharedHandler.loaderWrapper(
return this.sharedHandler.loaderWrapper(
this.provider.list(id),
(res) => {
const folders = []
Expand Down Expand Up @@ -142,44 +117,6 @@ module.exports = class ProviderView {
this.lastCheckbox = undefined
}

addFile (file) {
const tagFile = {
id: this.providerFileToId(file),
source: this.plugin.id,
data: file,
name: file.name || file.id,
type: file.mimeType,
isRemote: true,
body: {
fileId: file.id,
},
remote: {
companionUrl: this.plugin.opts.companionUrl,
url: `${this.provider.fileUrl(file.requestPath)}`,
body: {
fileId: file.id,
},
providerOptions: this.provider.opts,
},
}

const fileType = getFileType(tagFile)
// TODO Should we just always use the thumbnail URL if it exists?
if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = file.thumbnail
}
this.plugin.uppy.log('Adding remote file')
try {
this.plugin.uppy.addFile(tagFile)
return true
} catch (err) {
if (!err.isRestriction) {
this.plugin.uppy.log(err)
}
return false
}
}

/**
* Removes session token on client side.
*/
Expand Down Expand Up @@ -281,14 +218,6 @@ module.exports = class ProviderView {
})
}

providerFileToId (file) {
return generateFileID({
data: file,
name: file.name || file.id,
type: file.mimeType,
})
}

handleAuth () {
const authState = btoa(JSON.stringify({ origin: getOrigin() }))
const clientVersion = `@uppy/provider-views=${ProviderView.VERSION}`
Expand Down Expand Up @@ -333,29 +262,22 @@ module.exports = class ProviderView {
.some((pattern) => pattern.test(origin) || pattern.test(`${origin}/`)) // allowing for trailing '/'
}

handleError (error) {
const { uppy } = this.plugin
uppy.log(error.toString())
if (error.isAuthError) {
return
}
const message = uppy.i18n('companionError')
uppy.info({ message, details: error.toString() }, 'error', 5000)
}

handleScroll (e) {
const scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight)
async handleScroll (event) {
const path = this.nextPagePath || null

if (scrollPos < 50 && path && !this.#isHandlingScroll) {
this.provider.list(path)
.then((res) => {
const { files, folders } = this.plugin.getPluginState()
this.#updateFilesAndFolders(res, files, folders)
}).catch(this.handleError)
.then(() => { this.#isHandlingScroll = false }) // always called
if (this.shouldHandleScroll(event) && path) {
this.isHandlingScroll = true

this.#isHandlingScroll = true
try {
const response = await this.provider.list(path)
const { files, folders } = this.plugin.getPluginState()

this.#updateFilesAndFolders(response, files, folders)
} catch (error) {
this.handleError(error)
} finally {
this.isHandlingScroll = false
}
}
}

Expand Down Expand Up @@ -390,22 +312,11 @@ module.exports = class ProviderView {
return this.addFile(file)
})

this.#sharedHandler.loaderWrapper(Promise.all(promises), () => {
this.sharedHandler.loaderWrapper(Promise.all(promises), () => {
this.clearSelection()
}, () => {})
}

cancelPicking () {
this.clearSelection()

const dashboard = this.plugin.uppy.getPlugin('Dashboard')
if (dashboard) dashboard.hideAllPanels()
}

clearSelection () {
this.plugin.setPluginState({ currentSelection: [] })
}

render (state, viewOptions = {}) {
const { authenticated, didFirstRender } = this.plugin.getPluginState()

Expand All @@ -415,7 +326,7 @@ module.exports = class ProviderView {

const targetViewOptions = { ...this.opts, ...viewOptions }
const { files, folders, filterInput, loading, currentSelection } = this.plugin.getPluginState()
const { isChecked, toggleCheckbox, filterItems } = this.#sharedHandler
const { isChecked, toggleCheckbox, filterItems } = this.sharedHandler
const hasInput = filterInput !== ''
const headerProps = {
showBreadcrumbs: targetViewOptions.showBreadcrumbs,
Expand All @@ -437,7 +348,7 @@ module.exports = class ProviderView {
username: this.username,
getNextFolder: this.getNextFolder,
getFolder: this.getFolder,
filterItems: this.#sharedHandler.filterItems,
filterItems: this.sharedHandler.filterItems,
filterQuery: this.filterQuery,
logout: this.logout,
handleScroll: this.handleScroll,
Expand Down

0 comments on commit 2853116

Please sign in to comment.