Socket
Socket
Sign inDemoInstall

@uppy/provider-views

Package Overview
Dependencies
Maintainers
6
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uppy/provider-views - npm Package Compare versions

Comparing version 3.3.0 to 3.3.1

7

CHANGELOG.md
# @uppy/provider-views
## 3.3.1
Released: 2023-06-19
Included in: Uppy v3.10.0
- @uppy/provider-views: Fix range selection not resetting and computing correctly (Terence C / #4415)
## 3.3.0

@@ -4,0 +11,0 @@

2

lib/Breadcrumbs.js
import { h, Fragment } from 'preact';
const Breadcrumb = props => {

@@ -15,3 +14,2 @@ const {

};
export default (props => {

@@ -18,0 +16,0 @@ const {

@@ -8,3 +8,2 @@ import { h } from 'preact';

const VIRTUAL_SHARED_DIR = 'shared-with-me';
function Browser(props) {

@@ -63,3 +62,2 @@ const {

}
if (!folders.length && !files.length) {

@@ -70,3 +68,2 @@ return h("div", {

}
return h("div", {

@@ -77,3 +74,4 @@ className: "uppy-ProviderBrowser-body"

onScroll: handleScroll,
role: "listbox" // making <ul> not focusable for firefox
role: "listbox"
// making <ul> not focusable for firefox
,

@@ -83,3 +81,2 @@ tabIndex: "-1"

var _isChecked;
return Item({

@@ -127,3 +124,2 @@ columns,

}
export default Browser;

@@ -9,3 +9,2 @@ import { Component, toChildArray } from 'preact';

}
render() {

@@ -17,3 +16,2 @@ const {

}
}
import { h } from 'preact';
import classNames from 'classnames';
function GridListItem(props) {

@@ -29,2 +28,3 @@ const {

onKeyDown: recordShiftKeyPress,
onMouseDown: recordShiftKeyPress,
name: "listitem",

@@ -41,3 +41,2 @@ id: id,

}
export default GridListItem;
import { h } from 'preact';
function FileIcon() {

@@ -15,3 +14,2 @@ return h("svg", {

}
function FolderIcon() {

@@ -31,3 +29,2 @@ return h("svg", {

}
function VideoIcon() {

@@ -48,3 +45,2 @@ return h("svg", {

}
export default (props => {

@@ -55,13 +51,9 @@ const {

if (itemIconString === null) return undefined;
switch (itemIconString) {
case 'file':
return h(FileIcon, null);
case 'folder':
return h(FolderIcon, null);
case 'video':
return h(VideoIcon, null);
default:

@@ -68,0 +60,0 @@ {

@@ -1,2 +0,4 @@

import { h } from 'preact'; // if folder:
import { h } from 'preact';
// if folder:
// + checkbox (selects all files from folder)

@@ -32,3 +34,5 @@ // + folder name (opens folder)

onChange: toggleCheckbox,
onKeyDown: recordShiftKeyPress // for the <label/>
onKeyDown: recordShiftKeyPress,
onMouseDown: recordShiftKeyPress
// for the <label/>
,

@@ -43,3 +47,4 @@ name: "listitem",

"data-uppy-super-focusable": true
}) : null, type === 'file' ? // label for a checkbox
}) : null, type === 'file' ?
// label for a checkbox
h("label", {

@@ -50,3 +55,4 @@ htmlFor: id,

className: "uppy-ProviderBrowserItem-iconWrap"
}, itemIconEl), showTitles && title) : // button to open a folder
}, itemIconEl), showTitles && title) :
// button to open a folder
h("button", {

@@ -63,3 +69,2 @@ type: "button",

}
export default ListItem;
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { h } from 'preact';

@@ -27,6 +26,6 @@ import classNames from 'classnames';

});
switch (viewType) {
case 'grid':
return h(GridListItem // eslint-disable-next-line react/jsx-props-no-spreading
return h(GridListItem
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, props, {

@@ -36,5 +35,5 @@ className: className,

}));
case 'list':
return (// eslint-disable-next-line react/jsx-props-no-spreading
return (
// eslint-disable-next-line react/jsx-props-no-spreading
h(ListItem, _extends({}, props, {

@@ -45,5 +44,5 @@ className: className,

);
case 'unsplash':
return (// eslint-disable-next-line react/jsx-props-no-spreading
return (
// eslint-disable-next-line react/jsx-props-no-spreading
h(GridListItem, _extends({}, props, {

@@ -60,3 +59,2 @@ className: className,

);
default:

@@ -63,0 +61,0 @@ throw new Error(`There is no such type ${viewType}`);

@@ -9,3 +9,4 @@ import { h } from 'preact';

className: "uppy-Provider-loading"
}, h("span", null, i18n('loading')), typeof loading === 'string' && // todo improve this, see discussion in https://github.com/transloadit/uppy/pull/4399#discussion_r1162564445
}, h("span", null, i18n('loading')), typeof loading === 'string' &&
// todo improve this, see discussion in https://github.com/transloadit/uppy/pull/4399#discussion_r1162564445
h("span", {

@@ -12,0 +13,0 @@ style: {

import { h } from 'preact';
function GoogleIcon() {

@@ -37,3 +36,2 @@ return h("svg", {

}
function AuthView(props) {

@@ -45,5 +43,5 @@ const {

handleAuth
} = props; // In order to comply with Google's brand we need to create a different button
} = props;
// In order to comply with Google's brand we need to create a different button
// for the Google Drive plugin
const isGoogleDrive = pluginName === 'Google Drive';

@@ -75,3 +73,2 @@ const pluginNameComponent = h("span", {

}
export default AuthView;

@@ -5,3 +5,2 @@ import User from "./User.js";

const components = [];
if (props.showBreadcrumbs) {

@@ -15,3 +14,2 @@ components.push(Breadcrumbs({

}
components.push(User({

@@ -18,0 +16,0 @@ logout: props.logout,

function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
var id = 0;
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
import { h } from 'preact'; // eslint-disable-next-line import/no-unresolved
import { h } from 'preact';
// eslint-disable-next-line import/no-unresolved
import PQueue from 'p-queue';

@@ -18,5 +15,4 @@ import { getSafeFileId } from '@uppy/utils/lib/generateFileID';

const packageJson = {
"version": "3.3.0"
"version": "3.3.1"
};
function getOrigin() {

@@ -26,3 +22,2 @@ // eslint-disable-next-line no-restricted-globals

}
function getRegex(value) {

@@ -32,10 +27,7 @@ if (typeof value === 'string') {

}
if (value instanceof RegExp) {
return value;
}
return undefined;
}
function isOriginAllowed(origin, allowedOrigin) {

@@ -45,9 +37,7 @@ const patterns = Array.isArray(allowedOrigin) ? allowedOrigin.map(getRegex) : [getRegex(allowedOrigin)];

}
/**
* Class to easily generate generic views for Provider plugins
*/
var _updateFilesAndFolders = /*#__PURE__*/_classPrivateFieldLooseKey("updateFilesAndFolders");
export default class ProviderView extends View {

@@ -59,4 +49,4 @@ /**

constructor(plugin, opts) {
super(plugin, opts); // set default options
super(plugin, opts);
// set default options
Object.defineProperty(this, _updateFilesAndFolders, {

@@ -70,8 +60,11 @@ value: _updateFilesAndFolders2

showBreadcrumbs: true
}; // merge default options with the ones set by user
};
this.opts = { ...defaultOptions,
// merge default options with the ones set by user
this.opts = {
...defaultOptions,
...opts
}; // Logic
};
// Logic
this.filterQuery = this.filterQuery.bind(this);

@@ -84,6 +77,8 @@ this.clearFilter = this.clearFilter.bind(this);

this.handleScroll = this.handleScroll.bind(this);
this.donePicking = this.donePicking.bind(this); // Visual
this.donePicking = this.donePicking.bind(this);
this.render = this.render.bind(this); // Set default state for the plugin
// Visual
this.render = this.render.bind(this);
// Set default state for the plugin
this.plugin.setPluginState({

@@ -98,8 +93,8 @@ authenticated: false,

});
} // eslint-disable-next-line class-methods-use-this
}
tearDown() {// Nothing.
// eslint-disable-next-line class-methods-use-this
tearDown() {
// Nothing.
}
/**

@@ -113,3 +108,2 @@ * Based on folder ID, fetch a new folder and update it to state

this.setLoading(true);
try {

@@ -122,3 +116,2 @@ const res = await this.provider.list(id);

const index = state.directories.findIndex(dir => id === dir.id);
if (index !== -1) {

@@ -132,7 +125,4 @@ updatedDirectories = state.directories.slice(0, index + 1);

}
this.username = res.username || this.username;
_classPrivateFieldLooseBase(this, _updateFilesAndFolders)[_updateFilesAndFolders](res, files, folders);
this.plugin.setPluginState({

@@ -142,2 +132,3 @@ directories: updatedDirectories,

});
this.lastCheckbox = undefined;
} catch (err) {

@@ -149,2 +140,3 @@ this.handleError(err);

}
/**

@@ -155,4 +147,2 @@ * Fetches new folder

*/
getNextFolder(folder) {

@@ -162,7 +152,6 @@ this.getFolder(folder.requestPath, folder.name);

}
/**
* Removes session token on client side.
*/
logout() {

@@ -178,3 +167,2 @@ this.provider.logout().then(res => {

}
const newState = {

@@ -191,3 +179,2 @@ authenticated: false,

}
filterQuery(input) {

@@ -198,3 +185,2 @@ this.plugin.setPluginState({

}
clearFilter() {

@@ -205,3 +191,2 @@ this.plugin.setPluginState({

}
async handleAuth() {

@@ -218,3 +203,2 @@ await this.provider.ensurePreAuth();

const authWindow = window.open(link, '_blank');
const handleToken = e => {

@@ -225,11 +209,9 @@ if (e.source !== authWindow) {

}
if (!isOriginAllowed(e.origin, this.plugin.opts.companionAllowedHosts) || e.source !== authWindow) {
this.plugin.uppy.log(`rejecting event from ${e.origin} vs allowed pattern ${this.plugin.opts.companionAllowedHosts}`);
} // Check if it's a string before doing the JSON.parse to maintain support
}
// Check if it's a string before doing the JSON.parse to maintain support
// for older Companion versions that used object references
const data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;
if (data.error) {

@@ -246,3 +228,2 @@ this.plugin.uppy.log('auth aborted', 'warning');

}
if (!data.token) {

@@ -252,3 +233,2 @@ this.plugin.uppy.log('did not receive token from auth window', 'error');

}
authWindow.close();

@@ -259,12 +239,8 @@ window.removeEventListener('message', handleToken);

};
window.addEventListener('message', handleToken);
}
async handleScroll(event) {
const path = this.nextPagePath || null;
if (this.shouldHandleScroll(event) && path) {
this.isHandlingScroll = true;
try {

@@ -276,3 +252,2 @@ const response = await this.provider.list(path);

} = this.plugin.getPluginState();
_classPrivateFieldLooseBase(this, _updateFilesAndFolders)[_updateFilesAndFolders](response, files, folders);

@@ -286,6 +261,4 @@ } catch (error) {

}
async recursivelyListAllFiles(path, queue, onFiles) {
let curPath = path;
while (curPath) {

@@ -296,4 +269,5 @@ const res = await this.provider.list(curPath);

const folders = res.items.filter(item => item.isFolder);
onFiles(files); // recursively queue call to self for each folder
onFiles(files);
// recursively queue call to self for each folder
const promises = folders.map(async folder => queue.add(async () => this.recursivelyListAllFiles(folder.requestPath, queue, onFiles)));

@@ -306,3 +280,2 @@ await Promise.all(promises); // in case we get an error

this.setLoading(true);
try {

@@ -314,3 +287,2 @@ const {

const newFiles = [];
for (const file of currentSelection) {

@@ -327,11 +299,10 @@ if (file.isFolder) {

});
const onFiles = files => {
for (const newFile of files) {
const tagFile = this.getTagFile(newFile);
const id = getSafeFileId(tagFile); // If the same folder is added again, we don't want to send
const id = getSafeFileId(tagFile);
// If the same folder is added again, we don't want to send
// X amount of duplicate file notifications, we want to say
// the folder was already added. This checks if all files are duplicate,
// if that's the case, we don't add the files.
if (!this.plugin.uppy.checkIfFileAlreadyExists(id)) {

@@ -344,11 +315,8 @@ newFiles.push(newFile);

}
isEmpty = false;
}
};
await this.recursivelyListAllFiles(requestPath, queue, onFiles);
await queue.onIdle();
let message;
if (isEmpty) {

@@ -369,3 +337,2 @@ message = this.plugin.uppy.i18n('emptyFolderAdded');

}
messages.push(message);

@@ -375,3 +342,5 @@ } else {

}
} // Note: this.plugin.uppy.addFiles must be only run once we are done fetching all files,
}
// Note: this.plugin.uppy.addFiles must be only run once we are done fetching all files,
// because it will cause the loading screen to disappear,

@@ -381,4 +350,2 @@ // and that will allow the user to start the upload, so we need to make sure we have

// see https://github.com/transloadit/uppy/pull/4384
this.plugin.uppy.log('Adding remote provider files');

@@ -397,10 +364,7 @@ this.plugin.uppy.addFiles(newFiles.map(file => this.getTagFile(file)));

}
render(state, viewOptions) {
var _this = this;
if (viewOptions === void 0) {
viewOptions = {};
}
const {

@@ -413,8 +377,7 @@ authenticated,

} = this.plugin.uppy;
if (!didFirstRender) {
this.preFirstRender();
}
const targetViewOptions = { ...this.opts,
const targetViewOptions = {
...this.opts,
...viewOptions

@@ -481,3 +444,2 @@ };

};
if (loading) {

@@ -491,3 +453,2 @@ return h(CloseWrapper, {

}
if (!authenticated) {

@@ -504,3 +465,2 @@ return h(CloseWrapper, {

}
return h(CloseWrapper, {

@@ -510,5 +470,3 @@ onUnmount: this.clearSelection

}
}
function _updateFilesAndFolders2(res, files, folders) {

@@ -528,3 +486,2 @@ this.nextPagePath = res.nextPagePath;

}
ProviderView.VERSION = packageJson.version;
import { h, Fragment } from 'preact';
import { useEffect, useState, useCallback } from 'preact/hooks';
import { nanoid } from 'nanoid/non-secure'; // import debounce from 'lodash.debounce'
import { nanoid } from 'nanoid/non-secure';
// import debounce from 'lodash.debounce'

@@ -18,3 +19,4 @@ export default function SearchFilterInput(props) {

} = props;
const [searchText, setSearchText] = useState(searchTerm != null ? searchTerm : ''); // const debouncedSearch = debounce((q) => search(q), 1000)
const [searchText, setSearchText] = useState(searchTerm != null ? searchTerm : '');
// const debouncedSearch = debounce((q) => search(q), 1000)

@@ -30,3 +32,2 @@ const validateAndSearch = useCallback(ev => {

}, [setSearchText, searchOnInput, search]);
const handleReset = () => {

@@ -36,3 +37,2 @@ setSearchText('');

};
const [form] = useState(() => {

@@ -39,0 +39,0 @@ const formEl = document.createElement('form');

function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
var id = 0;
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
import { h } from 'preact';

@@ -13,3 +10,3 @@ import SearchFilterInput from "../SearchFilterInput.js";

const packageJson = {
"version": "3.3.0"
"version": "3.3.1"
};

@@ -20,5 +17,3 @@ /**

*/
var _updateFilesAndInputMode = /*#__PURE__*/_classPrivateFieldLooseKey("updateFilesAndInputMode");
export default class SearchProviderView extends View {

@@ -30,4 +25,5 @@ /**

constructor(plugin, opts) {
super(plugin, opts); // set default options
super(plugin, opts);
// set default options
Object.defineProperty(this, _updateFilesAndInputMode, {

@@ -41,8 +37,11 @@ value: _updateFilesAndInputMode2

showBreadcrumbs: false
}; // merge default options with the ones set by user
};
this.opts = { ...defaultOptions,
// merge default options with the ones set by user
this.opts = {
...defaultOptions,
...opts
}; // Logic
};
// Logic
this.search = this.search.bind(this);

@@ -52,4 +51,5 @@ this.clearSearch = this.clearSearch.bind(this);

this.handleScroll = this.handleScroll.bind(this);
this.donePicking = this.donePicking.bind(this); // Visual
this.donePicking = this.donePicking.bind(this);
// Visual
this.render = this.render.bind(this);

@@ -64,15 +64,15 @@ this.defaultState = {

searchTerm: null
}; // Set default state for the plugin
};
// Set default state for the plugin
this.plugin.setPluginState(this.defaultState);
} // eslint-disable-next-line class-methods-use-this
}
tearDown() {// Nothing.
// eslint-disable-next-line class-methods-use-this
tearDown() {
// Nothing.
}
resetPluginState() {
this.plugin.setPluginState(this.defaultState);
}
async search(query) {

@@ -82,3 +82,2 @@ const {

} = this.plugin.getPluginState();
if (query && query === searchTerm) {

@@ -88,8 +87,5 @@ // no need to search again as this is the same as the previous search

}
this.setLoading(true);
try {
const res = await this.provider.search(query);
_classPrivateFieldLooseBase(this, _updateFilesAndInputMode)[_updateFilesAndInputMode](res, []);

@@ -102,3 +98,2 @@ } catch (err) {

}
clearSearch() {

@@ -111,9 +106,6 @@ this.plugin.setPluginState({

}
async handleScroll(event) {
const query = this.nextPageQuery || null;
if (this.shouldHandleScroll(event) && query) {
this.isHandlingScroll = true;
try {

@@ -125,3 +117,2 @@ const {

const response = await this.provider.search(searchTerm, query);
_classPrivateFieldLooseBase(this, _updateFilesAndInputMode)[_updateFilesAndInputMode](response, files);

@@ -135,3 +126,2 @@ } catch (error) {

}
donePicking() {

@@ -145,10 +135,7 @@ const {

}
render(state, viewOptions) {
var _this = this;
if (viewOptions === void 0) {
viewOptions = {};
}
const {

@@ -162,8 +149,7 @@ didFirstRender,

} = this.plugin.uppy;
if (!didFirstRender) {
this.preFirstRender();
}
const targetViewOptions = { ...this.opts,
const targetViewOptions = {
...this.opts,
...viewOptions

@@ -181,3 +167,4 @@ };

toggleCheckbox,
filterItems
filterItems,
recordShiftKeyPress
} = this;

@@ -188,2 +175,3 @@ const hasInput = filterInput !== '';

toggleCheckbox,
recordShiftKeyPress,
currentSelection,

@@ -217,3 +205,2 @@ files: hasInput ? filterItems(files) : files,

};
if (isInputMode) {

@@ -234,3 +221,2 @@ return h(CloseWrapper, {

}
return h(CloseWrapper, {

@@ -240,5 +226,3 @@ onUnmount: this.resetPluginState

}
}
function _updateFilesAndInputMode2(res, files) {

@@ -256,3 +240,2 @@ this.nextPageQuery = res.nextPageQuery;

}
SearchProviderView.VERSION = packageJson.version;

@@ -8,7 +8,5 @@ import getFileType from '@uppy/utils/lib/getFileType';

const state = this.plugin.getPluginState();
if (!state.filterInput || state.filterInput === '') {
return items;
}
return items.filter(folder => {

@@ -18,7 +16,12 @@ return folder.name.toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1;

};
this.recordShiftKeyPress = e => {
this.isShiftKeyPressed = e.shiftKey;
};
/**
* Toggles file/folder checkbox to on/off state while updating files list.
*
* Note that some extra complexity comes from supporting shift+click to
* toggle multiple checkboxes at once, which is done by getting all files
* in between last checked file and current one.
*/
this.toggleCheckbox = (e, file) => {

@@ -32,20 +35,23 @@ e.stopPropagation();

} = this.plugin.getPluginState();
const items = this.filterItems(folders.concat(files)); // Shift-clicking selects a single consecutive list of items
// starting at the previous click and deselects everything else.
const items = this.filterItems(folders.concat(files));
// Shift-clicking selects a single consecutive list of items
// starting at the previous click.
if (this.lastCheckbox && this.isShiftKeyPressed) {
const {
currentSelection
} = this.plugin.getPluginState();
const prevIndex = items.indexOf(this.lastCheckbox);
const currentIndex = items.indexOf(file);
const currentSelection = prevIndex < currentIndex ? items.slice(prevIndex, currentIndex + 1) : items.slice(currentIndex, prevIndex + 1);
const reducedCurrentSelection = []; // Check restrictions on each file in currentSelection,
const newSelection = prevIndex < currentIndex ? items.slice(prevIndex, currentIndex + 1) : items.slice(currentIndex, prevIndex + 1);
const reducedNewSelection = [];
// Check restrictions on each file in currentSelection,
// reduce it to only contain files that pass restrictions
for (const item of currentSelection) {
for (const item of newSelection) {
const {
uppy
} = this.plugin;
const restrictionError = uppy.validateRestrictions(remoteFileObjToLocal(item), [...uppy.getFiles(), ...reducedCurrentSelection]);
const restrictionError = uppy.validateRestrictions(remoteFileObjToLocal(item), [...uppy.getFiles(), ...reducedNewSelection]);
if (!restrictionError) {
reducedCurrentSelection.push(item);
reducedNewSelection.push(item);
} else {

@@ -57,9 +63,7 @@ uppy.info({

}
this.plugin.setPluginState({
currentSelection: reducedCurrentSelection
currentSelection: [...new Set([...currentSelection, ...reducedNewSelection])]
});
return;
}
this.lastCheckbox = file;

@@ -69,3 +73,2 @@ const {

} = this.plugin.getPluginState();
if (this.isChecked(file)) {

@@ -81,12 +84,10 @@ this.plugin.setPluginState({

};
this.isChecked = file => {
const {
currentSelection
} = this.plugin.getPluginState(); // comparing id instead of the file object, because the reference to the object
} = this.plugin.getPluginState();
// comparing id instead of the file object, because the reference to the object
// changes when we switch folders, and the file list is updated
return currentSelection.some(item => item.id === file.id);
};
this.plugin = plugin;

@@ -100,3 +101,2 @@ this.provider = opts.provider;

}
preFirstRender() {

@@ -107,5 +107,5 @@ this.plugin.setPluginState({

this.plugin.onFirstRender();
} // eslint-disable-next-line class-methods-use-this
}
// eslint-disable-next-line class-methods-use-this
shouldHandleScroll(event) {

@@ -120,3 +120,2 @@ const {

}
clearSelection() {

@@ -128,7 +127,5 @@ this.plugin.setPluginState({

}
cancelPicking() {
this.clearSelection();
const dashboard = this.plugin.uppy.getPlugin('Dashboard');
if (dashboard) {

@@ -138,3 +135,2 @@ dashboard.hideAllPanels();

}
handleError(error) {

@@ -146,7 +142,5 @@ const {

uppy.log(error.toString());
if (error.isAuthError) {
return;
}
uppy.info({

@@ -156,5 +150,5 @@ message,

}, 'error', 5000);
} // todo document what is a "tagFile" or get rid of this concept
}
// todo document what is a "tagFile" or get rid of this concept
getTagFile(file) {

@@ -183,8 +177,8 @@ const tagFile = {

};
const fileType = getFileType(tagFile); // TODO Should we just always use the thumbnail URL if it exists?
const fileType = getFileType(tagFile);
// TODO Should we just always use the thumbnail URL if it exists?
if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = file.thumbnail;
}
if (file.author) {

@@ -194,6 +188,4 @@ if (file.author.name != null) tagFile.meta.authorName = String(file.author.name);

}
return tagFile;
}
setLoading(loading) {

@@ -204,3 +196,2 @@ this.plugin.setPluginState({

}
}
{
"name": "@uppy/provider-views",
"description": "View library for Uppy remote provider plugins.",
"version": "3.3.0",
"version": "3.3.1",
"license": "MIT",

@@ -23,3 +23,3 @@ "main": "lib/index.js",

"dependencies": {
"@uppy/utils": "^5.3.0",
"@uppy/utils": "^5.4.0",
"classnames": "^2.2.6",

@@ -31,4 +31,4 @@ "nanoid": "^4.0.0",

"peerDependencies": {
"@uppy/core": "^3.2.0"
"@uppy/core": "^3.2.1"
}
}

@@ -36,2 +36,3 @@ import { h } from 'preact'

onKeyDown={recordShiftKeyPress}
onMouseDown={recordShiftKeyPress}
name="listitem"

@@ -38,0 +39,0 @@ id={id}

@@ -39,2 +39,3 @@ import { h } from 'preact'

onKeyDown={recordShiftKeyPress}
onMouseDown={recordShiftKeyPress}
// for the <label/>

@@ -41,0 +42,0 @@ name="listitem"

@@ -127,2 +127,3 @@ import { h } from 'preact'

this.plugin.setPluginState({ directories: updatedDirectories, filterInput: '' })
this.lastCheckbox = undefined
} catch (err) {

@@ -129,0 +130,0 @@ this.handleError(err)

@@ -141,3 +141,3 @@ import { h } from 'preact'

const { files, folders, filterInput, loading, currentSelection } = this.plugin.getPluginState()
const { isChecked, toggleCheckbox, filterItems } = this
const { isChecked, toggleCheckbox, filterItems, recordShiftKeyPress } = this
const hasInput = filterInput !== ''

@@ -148,2 +148,3 @@

toggleCheckbox,
recordShiftKeyPress,
currentSelection,

@@ -150,0 +151,0 @@ files: hasInput ? filterItems(files) : files,

@@ -126,22 +126,23 @@ import getFileType from '@uppy/utils/lib/getFileType'

// Shift-clicking selects a single consecutive list of items
// starting at the previous click and deselects everything else.
// starting at the previous click.
if (this.lastCheckbox && this.isShiftKeyPressed) {
const { currentSelection } = this.plugin.getPluginState()
const prevIndex = items.indexOf(this.lastCheckbox)
const currentIndex = items.indexOf(file)
const currentSelection = (prevIndex < currentIndex)
const newSelection = (prevIndex < currentIndex)
? items.slice(prevIndex, currentIndex + 1)
: items.slice(currentIndex, prevIndex + 1)
const reducedCurrentSelection = []
const reducedNewSelection = []
// Check restrictions on each file in currentSelection,
// reduce it to only contain files that pass restrictions
for (const item of currentSelection) {
for (const item of newSelection) {
const { uppy } = this.plugin
const restrictionError = uppy.validateRestrictions(
remoteFileObjToLocal(item),
[...uppy.getFiles(), ...reducedCurrentSelection],
[...uppy.getFiles(), ...reducedNewSelection],
)
if (!restrictionError) {
reducedCurrentSelection.push(item)
reducedNewSelection.push(item)
} else {

@@ -151,3 +152,3 @@ uppy.info({ message: restrictionError.message }, 'error', uppy.opts.infoTimeout)

}
this.plugin.setPluginState({ currentSelection: reducedCurrentSelection })
this.plugin.setPluginState({ currentSelection: [...new Set([...currentSelection, ...reducedNewSelection])] })
return

@@ -154,0 +155,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc