Rename + list files bugfix
This commit is contained in:
1 parent
0df60ddd96
commit
42d2a3d919
5 files changed
+328
-58
No files matched your search
+223
-18
@@ -111,26 +111,65 @@ namespace Api {
|
||||
}
|
||||
}
|
||||
|
||||
protected function createFileList($res) {
|
||||
$files = array();
|
||||
foreach ($res as $row) {
|
||||
if ($row["uid"] === null) continue;
|
||||
$fileId = $row["uid"];
|
||||
$parentId = $row["parentId"];
|
||||
$fileName = $row["name"];
|
||||
$isDirectory = $row["directory"];
|
||||
$fileElement = array("uid" => $fileId, "name" => $fileName, "isDirectory" => $isDirectory);
|
||||
if ($isDirectory) {
|
||||
$fileElement["items"] = array();
|
||||
private function insert(&$files, $row) {
|
||||
$entry = array("uid" => $row["uid"], "name" => $row["name"], "isDirectory" => $row["directory"]);
|
||||
if ($row["directory"]) {
|
||||
$entry["items"] = array();
|
||||
} else {
|
||||
$fileElement["size"] = @filesize($row["path"]);
|
||||
$fileElement["mimeType"] = @mime_content_type($row["path"]);
|
||||
$entry["size"] = @filesize($row["path"]);
|
||||
$entry["mimeType"] = @mime_content_type($row["path"]);
|
||||
}
|
||||
|
||||
$dir =& $this->findDirectory($files, $parentId);
|
||||
$dir[$fileId] = $fileElement;
|
||||
unset($dir);
|
||||
$dir =& $this->findDirectory($files, $row["parentId"]);
|
||||
if ($dir !== $files || $row["parentId"] === null) {
|
||||
$dir[$row["uid"]] = $entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function createFileList($res) {
|
||||
|
||||
$files = array();
|
||||
|
||||
// Create temporary files
|
||||
$tempFiles = [];
|
||||
foreach ($res as $row) {
|
||||
$fileId = $row["uid"];
|
||||
$parentId = $row["parentId"];
|
||||
if ($fileId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// insert all files/dirs in the root directory
|
||||
if ($parentId === null) {
|
||||
$this->insert($files, $row);
|
||||
} else {
|
||||
// save other files temporary
|
||||
$tempFiles[$fileId] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// repeatedly try to find the directory
|
||||
// a bit ugly code over here..
|
||||
$filesToProcess = count($tempFiles);
|
||||
while (count($tempFiles) > 0) {
|
||||
|
||||
foreacH($tempFiles as $fileId => $row) {
|
||||
if ($this->insert($files, $row)) {
|
||||
unset($tempFiles[$fileId]);
|
||||
}
|
||||
}
|
||||
|
||||
// some files could not be inserted for some reason
|
||||
if (count($tempFiles) === $filesToProcess) {
|
||||
break;
|
||||
} else {
|
||||
$filesToProcess = count($tempFiles);
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
@@ -434,9 +473,175 @@ namespace Api\File {
|
||||
}
|
||||
}
|
||||
|
||||
class Rename extends FileAPI { }
|
||||
class Rename extends FileAPI {
|
||||
public function __construct(User $user, bool $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
"name" => new StringType("name", 64, false),
|
||||
"token" => new StringType("token", 36, true, null)
|
||||
));
|
||||
}
|
||||
|
||||
class Move extends FileAPI { }
|
||||
public function execute($values = array()) {
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fileId = $this->getParam("id");
|
||||
$newName = $this->getParam("name");
|
||||
$token = $this->getParam("token");
|
||||
|
||||
if (!$this->user->isLoggedIn() && is_null($token)) {
|
||||
return $this->createError("Permission denied (expected token)");
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$selectColumns = ($token !== null ? array("parent_id", "user_id") : array("parent_id"));
|
||||
$query = $sql->select(...$selectColumns)->from("UserFile");
|
||||
$this->filterFiles($sql, $query, $fileId, $token);
|
||||
$res = $query->execute();
|
||||
|
||||
$this->success = $res !== false;
|
||||
$this->lastError = $sql->getLastError();
|
||||
if (!$this->success) {
|
||||
return false;
|
||||
} else if (empty($res)) {
|
||||
return $this->createError("File not found");
|
||||
}
|
||||
|
||||
// check if file already exists
|
||||
$parentId = $res[0]["parent_id"];
|
||||
$userId = ($token === null) ? $this->user->getId() : $res[0]["user_id"];
|
||||
$res = $sql->select($sql->count())
|
||||
->from("UserFile")
|
||||
->where(new Compare("name", $newName))
|
||||
->where(new Compare("parent_id", $parentId))
|
||||
->where(new Compare("user_id", $userId))
|
||||
->execute();
|
||||
|
||||
$this->success = $res !== false;
|
||||
$this->lastError = $sql->getLastError();
|
||||
if (!$this->success) {
|
||||
return false;
|
||||
} else if ($res[0]["count"] > 0) {
|
||||
return $this->createError("A file or directory with this name does already exist");
|
||||
}
|
||||
|
||||
$res = $sql->update("UserFile")
|
||||
->set("name", $newName)
|
||||
->where(new Compare("parent_id", $parentId))
|
||||
->where(new Compare("user_id", $userId))
|
||||
->where(new Compare("uid", $fileId))
|
||||
->execute();
|
||||
|
||||
$this->success = $res !== false;
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Move extends FileAPI {
|
||||
|
||||
public function __construct(User $user, bool $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'parentId' => new Parameter('parentId', Parameter::TYPE_INT, true, null),
|
||||
"id" => new ArrayType("id", Parameter::TYPE_INT, true),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$fileIds = array_unique($this->getParam("id"));
|
||||
$destinationId = $this->getParam("parentId");
|
||||
$userId = $this->user->getId();
|
||||
|
||||
// check, if we are trying to do some illegal move
|
||||
if ($destinationId !== null && in_array($destinationId, $fileIds)) {
|
||||
return $this->createError("Cannot move a file to the given directory");
|
||||
}
|
||||
|
||||
$query = $sql->select("UserFile.uid", "directory", "name", "parent_id")->from("UserFile");
|
||||
$this->filterFiles($sql, $query, array_merge($fileIds, [$destinationId]));
|
||||
$query->orderBy("parent_id")->ascending();
|
||||
|
||||
$res = $query->execute();
|
||||
$this->success = ($res !== false);
|
||||
$this->lastError = $sql->getLastError();
|
||||
if (!$this->success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$foundFiles = array();
|
||||
$moveFiles = array();
|
||||
$skipDirectories = array();
|
||||
|
||||
foreach($res as $row) {
|
||||
$fileId = $row["uid"];
|
||||
$isDirectory = $row["directory"];
|
||||
$fileName = $row["name"];
|
||||
$filesDirectory = $row["parent_id"];
|
||||
if ($fileId === $destinationId) {
|
||||
if (!$isDirectory) {
|
||||
return $this->createError("Cannot move file: Destination is not a directory");
|
||||
}
|
||||
} else {
|
||||
$foundFiles[] = $fileId;
|
||||
|
||||
if ($filesDirectory === null || !in_array($filesDirectory, $skipDirectories)) {
|
||||
$moveFiles[$fileId] = $fileName;
|
||||
}
|
||||
|
||||
if ($isDirectory) {
|
||||
$skipDirectories[] = $fileId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($foundFiles) !== count($fileIds)) {
|
||||
foreach ($fileIds as $fileId) {
|
||||
if (!array_key_exists($fileId, $foundFiles)) {
|
||||
return $this->createError("File not found: $fileId");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for duplicates
|
||||
$res = $sql->select($sql->count())
|
||||
->from("UserFile")
|
||||
->where(new Compare("user_id", $userId))
|
||||
->where(new Compare("parent_id", $destinationId))
|
||||
->where(new CondIn("name", array_values($moveFiles)))
|
||||
->execute();
|
||||
|
||||
$this->success = $res !== false;
|
||||
$this->lastError = $sql->getLastError();
|
||||
if (!$this->success) {
|
||||
return false;
|
||||
} else if($res[0]["count"] > 0) {
|
||||
return $this->createError("Cannot move files: the destination directory already contains one or " .
|
||||
"more files or directories with the same name");
|
||||
}
|
||||
|
||||
// update parent ids
|
||||
$res = $sql->update("UserFile")
|
||||
->set("parent_id", $destinationId)
|
||||
->where(new Compare("user_id", $userId))
|
||||
->where(new CondIn("uid", array_keys($moveFiles)))
|
||||
->execute();
|
||||
|
||||
$this->success = $res !== false;
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Upload extends FileAPI {
|
||||
|
||||
|
||||
@@ -64,6 +64,14 @@ export default class API {
|
||||
return this.apiCall("file/createDirectory", { name: name, parentId: parentId });
|
||||
}
|
||||
|
||||
moveFiles(files, parentId = null) {
|
||||
return this.apiCall("file/move", { id: files, parentId: parentId });
|
||||
}
|
||||
|
||||
rename(id, name, token = null) {
|
||||
return this.apiCall("file/rename", { id: id, name: name, token: token });
|
||||
}
|
||||
|
||||
getRestrictions() {
|
||||
return this.apiCall("file/getRestrictions");
|
||||
}
|
||||
|
||||
@@ -17,10 +17,14 @@ export function FileBrowser(props) {
|
||||
let directories = props.directories || {};
|
||||
let restrictions = props.restrictions || {maxFiles: 0, maxSize: 0, extensions: ""};
|
||||
|
||||
let [popup, setPopup] = useState({visible: false, directoryName: "", directory: 0, type: "upload"});
|
||||
let [popup, setPopup] = useState({ visible: false, name: "", directory: 0, target: null, type: "createDirectory" });
|
||||
let [alerts, setAlerts] = useState([]);
|
||||
let [filesToUpload, setFilesToUpload] = useState([]);
|
||||
|
||||
function canUpload() {
|
||||
return api.loggedIn || (tokenObj.valid && tokenObj.type === "upload");
|
||||
}
|
||||
|
||||
function svgMiddle(key, scale = 1.0) {
|
||||
let width = 48 * scale;
|
||||
let height = 64 * scale;
|
||||
@@ -122,10 +126,6 @@ export function FileBrowser(props) {
|
||||
}
|
||||
}, [filesToUpload]);
|
||||
|
||||
function canUpload() {
|
||||
return api.loggedIn || (tokenObj.valid && tokenObj.type === "upload");
|
||||
}
|
||||
|
||||
function onAddUploadFiles(acceptedFiles, rejectedFiles) {
|
||||
|
||||
if (rejectedFiles && rejectedFiles.length > 0) {
|
||||
@@ -179,6 +179,13 @@ export function FileBrowser(props) {
|
||||
}
|
||||
}
|
||||
|
||||
let selectedIds = getSelectedIds();
|
||||
let selectedCount = selectedIds.length;
|
||||
let uploadZone = <></>;
|
||||
let writePermissions = canUpload();
|
||||
let uploadedFiles = [];
|
||||
let alertElements = [];
|
||||
|
||||
function createFileList(elements, indentation = 0) {
|
||||
let rows = [];
|
||||
let rowIndex = 0;
|
||||
@@ -224,6 +231,10 @@ export function FileBrowser(props) {
|
||||
<input type={"checkbox"} checked={!!fileElement.selected}
|
||||
onChange={(e) => onSelectFile(e, uid)}
|
||||
/>
|
||||
{ writePermissions ?
|
||||
<Icon icon={"pencil-alt"} title={"Rename"} className={"ml-2 clickable text-secondary"}
|
||||
style={{marginTop: "-17px"}} onClick={() => onPopupOpen("rename", uid)} /> :
|
||||
<></> }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
@@ -236,14 +247,6 @@ export function FileBrowser(props) {
|
||||
return rows;
|
||||
}
|
||||
|
||||
let rows = createFileList(files);
|
||||
let selectedIds = getSelectedIds();
|
||||
let selectedCount = selectedIds.length;
|
||||
let uploadZone = <></>;
|
||||
let writePermissions = canUpload();
|
||||
let uploadedFiles = [];
|
||||
let alertElements = [];
|
||||
|
||||
for (let i = 0; i < alerts.length; i++) {
|
||||
const alert = alerts[i];
|
||||
alertElements.push(
|
||||
@@ -287,6 +290,7 @@ export function FileBrowser(props) {
|
||||
setFilesToUpload(files);
|
||||
}
|
||||
|
||||
let rows = createFileList(files);
|
||||
if (writePermissions) {
|
||||
|
||||
for (let i = 0; i < filesToUpload.length; i++) {
|
||||
@@ -340,6 +344,54 @@ export function FileBrowser(props) {
|
||||
</>;
|
||||
}
|
||||
|
||||
let singleButton = {
|
||||
gridColumnStart: 1,
|
||||
gridColumnEnd: 3,
|
||||
width: "40%",
|
||||
margin: "0 auto"
|
||||
};
|
||||
|
||||
function createPopup() {
|
||||
let title = "";
|
||||
let inputs = [];
|
||||
|
||||
if (popup.type === "createDirectory" || popup.type === "moveFiles") {
|
||||
inputs.push(
|
||||
<div className={"form-group"} key={"select-directory"}>
|
||||
<label>Destination Directory:</label>
|
||||
<select value={popup.directory} className={"form-control"}
|
||||
onChange={(e) => onPopupChange(e, "directory")}>
|
||||
{options}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (popup.type === "createDirectory" || popup.type === "rename") {
|
||||
inputs.push(
|
||||
<div className={"form-group"} key={"input-name"}>
|
||||
<label>{ popup.type === "createDirectory" ? "Create Directory" : "New Name" }</label>
|
||||
<input type={"text"} className={"form-control"} value={popup.name} maxLength={32}
|
||||
placeholder={"Enter name…"}
|
||||
onChange={(e) => onPopupChange(e, "name")}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (popup.type === "createDirectory") {
|
||||
title = "Create Directory";
|
||||
} else if (popup.type === "moveFiles") {
|
||||
title = "Move Files";
|
||||
} else if (popup.type === "rename") {
|
||||
title = "Rename File or Directory";
|
||||
}
|
||||
|
||||
return <Popup title={title} visible={popup.visible} buttons={["Ok", "Cancel"]} onClose={onPopupClose}
|
||||
onClick={onPopupButton}>
|
||||
{ inputs }
|
||||
</Popup>
|
||||
}
|
||||
|
||||
return <>
|
||||
<h4>
|
||||
<Icon icon={"sync"} className={"mx-3 clickable small"} onClick={fetchFiles}/>
|
||||
@@ -366,12 +418,11 @@ export function FileBrowser(props) {
|
||||
</tbody>
|
||||
</table>
|
||||
<div className={"file-control-buttons"}>
|
||||
<button type={"button"} className={"btn btn-success"} disabled={selectedCount === 0}
|
||||
<button type={"button"} className={"btn btn-success"} disabled={selectedCount === 0} style={!writePermissions ? singleButton : {}}
|
||||
onClick={() => onDownload(selectedIds)}>
|
||||
<Icon icon={"download"} className={"mr-1"}/>
|
||||
Download Selected Files ({selectedCount})
|
||||
</button>
|
||||
<span/>
|
||||
{
|
||||
writePermissions ?
|
||||
<>
|
||||
@@ -381,11 +432,18 @@ export function FileBrowser(props) {
|
||||
Delete Selected Files ({selectedCount})
|
||||
</button>
|
||||
{api.loggedIn ?
|
||||
<>
|
||||
<button type={"button"} className={"btn btn-info"}
|
||||
onClick={(e) => onPopupOpen("createDirectory")}>
|
||||
<Icon icon={"plus"} className={"mr-1"}/>
|
||||
Create Directory
|
||||
</button> :
|
||||
</button>
|
||||
<button type={"button"} className={"btn btn-primary"} disabled={selectedCount === 0}
|
||||
onClick={(e) => onPopupOpen("moveFiles")}>
|
||||
<Icon icon={"plus"} className={"mr-1"}/>
|
||||
Move Selected Files ({selectedCount})
|
||||
</button>
|
||||
</>:
|
||||
<></>
|
||||
}
|
||||
</>
|
||||
@@ -402,28 +460,11 @@ export function FileBrowser(props) {
|
||||
<div>
|
||||
{alertElements}
|
||||
</div>
|
||||
<Popup title={"Create Directory"} visible={popup.visible} buttons={["Ok", "Cancel"]} onClose={onPopupClose}
|
||||
onClick={onPopupButton}>
|
||||
<div className={"form-group"}>
|
||||
<label>Destination Directory:</label>
|
||||
<select value={popup.directory} className={"form-control"}
|
||||
onChange={(e) => onPopupChange(e, "directory")}>
|
||||
{options}
|
||||
</select>
|
||||
</div>
|
||||
{popup.type !== "upload" ?
|
||||
<div className={"form-group"}>
|
||||
<label>Directory Name</label>
|
||||
<input type={"text"} className={"form-control"} value={popup.directoryName} maxLength={32}
|
||||
placeholder={"Enter name…"}
|
||||
onChange={(e) => onPopupChange(e, "directoryName")}/>
|
||||
</div> : <></>
|
||||
}
|
||||
</Popup>
|
||||
{ createPopup() }
|
||||
</>;
|
||||
|
||||
function onPopupOpen(type) {
|
||||
setPopup({...popup, visible: true, type: type});
|
||||
function onPopupOpen(type, target = null) {
|
||||
setPopup({...popup, visible: true, type: type, target: target});
|
||||
}
|
||||
|
||||
function onPopupClose() {
|
||||
@@ -439,13 +480,29 @@ export function FileBrowser(props) {
|
||||
if (btn === "Ok") {
|
||||
let parentId = popup.directory === 0 ? null : popup.directory;
|
||||
if (popup.type === "createDirectory") {
|
||||
api.createDirectory(popup.directoryName, parentId).then((res) => {
|
||||
api.createDirectory(popup.name, parentId).then((res) => {
|
||||
if (!res.success) {
|
||||
pushAlert(res, "Error creating directory");
|
||||
} else {
|
||||
fetchFiles();
|
||||
}
|
||||
});
|
||||
} else if (popup.type === "moveFiles") {
|
||||
api.moveFiles(selectedIds, parentId).then((res) => {
|
||||
if (!res.success) {
|
||||
pushAlert(res, "Error moving files");
|
||||
} else {
|
||||
fetchFiles();
|
||||
}
|
||||
});
|
||||
} else if (popup.type === "rename") {
|
||||
api.rename(popup.target, popup.name, tokenObj.valid ? tokenObj.value : null).then((res) => {
|
||||
if (!res.success) {
|
||||
pushAlert(res, "Error renaming file or directory");
|
||||
} else {
|
||||
fetchFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +84,9 @@ class FileControlPanel extends React.Component {
|
||||
if (this.onSelectFile(e, uid, fileElement.items)) {
|
||||
if (!e.target.checked) {
|
||||
fileElement.selected = false;
|
||||
} else if (this.getSelectedIds(fileElement.items, false).length === Object.values(fileElement.items).length) {
|
||||
}/* else if (this.getSelectedIds(fileElement.items, false).length === Object.values(fileElement.items).length) {
|
||||
fileElement.selected = true;
|
||||
}
|
||||
}*/
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -299,4 +299,4 @@ e.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,w=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?w.postMessage(null):(v=!1,g=null)}catch(e){throw w.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,w.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function Y(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,O=null,H=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,Y(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=H;try{for(C(n),O=T(x);null!==O&&(!(O.expirationTime>n)||e&&!o());){var s=O.callback;if(null!==s){O.callback=null,H=O.priorityLevel;var u=s(O.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?O.callback=u:O===T(x)&&D(x),C(n)}else D(x);O=T(x)}if(null!==O)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{O=null,H=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return H},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(H){case 1:case 2:case 3:var t=3;break;default:t=H}var n=H;H=t;try{return e()}finally{H=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=H;H=e;try{return t()}finally{H=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,Y(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,Y(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==O&&null!==O&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<O.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=H;return function(){var n=H;H=t;try{return e.apply(this,arguments)}finally{H=n}}}},function(e,t,n){"use strict";(function(e){if(n(286),n(483),n(484),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,
Line truncated
|
||||
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,w=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?w.postMessage(null):(v=!1,g=null)}catch(e){throw w.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,w.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function Y(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,O=null,H=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,Y(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=H;try{for(C(n),O=T(x);null!==O&&(!(O.expirationTime>n)||e&&!o());){var s=O.callback;if(null!==s){O.callback=null,H=O.priorityLevel;var u=s(O.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?O.callback=u:O===T(x)&&D(x),C(n)}else D(x);O=T(x)}if(null!==O)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{O=null,H=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return H},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(H){case 1:case 2:case 3:var t=3;break;default:t=H}var n=H;H=t;try{return e()}finally{H=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=H;H=e;try{return t()}finally{H=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,Y(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,Y(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==O&&null!==O&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<O.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=H;return function(){var n=H;H=t;try{return e.apply(this,arguments)}finally{H=n}}}},function(e,t,n){"use strict";(function(e){if(n(286),n(483),n(484),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,
Line truncated
|
||||
Reference in new issue
Block a user