mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 08:28:42 +00:00
Merge pull request #2816 from appwrite/feat-console-resumable-upload
This commit is contained in:
commit
f8cea8cc18
10 changed files with 235 additions and 120 deletions
|
|
@ -223,20 +223,20 @@
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<section class="upload-box" x-data x-show="$store.uploader.files.length > 0">
|
||||
<section class="upload-box" x-data x-show="$store.uploader.files().length > 0">
|
||||
<div class="upload-box-header">
|
||||
<h4 class="upload-box-title">
|
||||
<span class="text">Uploading files</span>
|
||||
<span class="amount" x-text="$store.uploader.files.length"></span>
|
||||
<span class="amount" x-text="$store.uploader.files().length"></span>
|
||||
</h4>
|
||||
<button class="icon-button" :class="$store.uploader.isOpen ? '' : 'is-open'" aria-label="toggle upload box" @click="$store.uploader.toggle()"><span class="icon-chevron-down" aria-hidden="true"></span></button>
|
||||
<button class="icon-button" aria-label="close upload box"><span class="icon-x" aria-hidden="true"></span></button>
|
||||
<button class="icon-button" @click="$store.uploader.cancelAll()" aria-label="close upload box"><span class="icon-x" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
<div class="upload-box-content" :class="$store.uploader.isOpen ? 'is-open' : ''">
|
||||
<ul class="upload-box-list">
|
||||
<template x-if="$store.uploader.files.length > 0">
|
||||
<template x-for="file in $store.uploader.files" :key="file.id">
|
||||
<li class="upload-box-item">
|
||||
<template x-if="$store.uploader.files().length > 0">
|
||||
<template x-for="file in $store.uploader.files()" :key="file.id">
|
||||
<li x-show="!file.cancelled" class="upload-box-item">
|
||||
<div class="upload-image u-margin-inline-end-16" :class="file.completed ? 'is-finished' : ''">
|
||||
<div class="progress"
|
||||
:style="'--progress-value:' + file.progress"
|
||||
|
|
@ -244,7 +244,8 @@
|
|||
role="progressbar"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"></div>
|
||||
<span class="icon" x-text="file.progress"></span>
|
||||
<span x-show="!file.completed" class="icon" x-text="file.progress + '%'"></span>
|
||||
<span x-show="file.completed" class="icon icon-file"></span>
|
||||
</div>
|
||||
<label for="file1" class="file-name trim-inner-text" x-text="file.name"></label>
|
||||
<span class="pill is-failed" x-show="file.failed">failed</span>
|
||||
|
|
|
|||
25
public/dist/scripts/app-all.js
vendored
25
public/dist/scripts/app-all.js
vendored
|
|
@ -64,7 +64,8 @@ if(typeof scopes!=='undefined'){payload['scopes']=scopes;}
|
|||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
if(typeof window!=='undefined'&&(window===null||window===void 0?void 0:window.location)){window.location.href=uri.toString();}
|
||||
else{return uri;}},getSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createVerification:(url)=>__awaiter(this,void 0,void 0,function*(){if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/account/verification';let payload={};if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateVerification:(userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
|
|
@ -304,10 +305,10 @@ if(typeof code==='undefined'){throw new AppwriteException('Missing required para
|
|||
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof command!=='undefined'){payload['command']=command;}
|
||||
if(typeof code!=='undefined'){payload['code']=code;}
|
||||
const uri=new URL(this.config.endpoint+path);const size=code.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}
|
||||
else{let id=undefined;let response=undefined;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(let counter=0;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);const headers={'content-type':'multipart/form-data','content-range':'bytes '+start+'-'+end+'/'+size};if(id){headers['x-appwrite-id']=id;}
|
||||
let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(counter;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);headers['content-range']='bytes '+start+'-'+end+'/'+size;if(id){headers['x-appwrite-id']=id;}
|
||||
const stream=code.slice(start,end+1);payload['code']=new File([stream],code.name);response=yield this.call('post',uri,headers,payload);if(!id){id=response['$id'];}
|
||||
if(onProgress){onProgress(Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100);}}
|
||||
return response;}}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(onProgress){onProgress({$id:response.$id,progress:Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100,sizeUpploaded:end+1,chunksTotal:response.chunksTotal,chunksUploaded:response.chunksUploaded});}}
|
||||
return response;}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
|
|
@ -491,10 +492,12 @@ if(typeof file!=='undefined'){payload['file']=file;}
|
|||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
const uri=new URL(this.config.endpoint+path);const size=file.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}
|
||||
else{let id=undefined;let response=undefined;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(let counter=0;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);const headers={'content-type':'multipart/form-data','content-range':'bytes '+start+'-'+end+'/'+size};if(id){headers['x-appwrite-id']=id;}
|
||||
let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);if(fileId!='unique()'){try{response=yield this.call('GET',new URL(this.config.endpoint+path+'/'+fileId),headers);counter=response.chunksUploaded;}
|
||||
catch(e){}}
|
||||
for(counter;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);headers['content-range']='bytes '+start+'-'+end+'/'+size;if(id){headers['x-appwrite-id']=id;}
|
||||
const stream=file.slice(start,end+1);payload['file']=new File([stream],file.name);response=yield this.call('post',uri,headers,payload);if(!id){id=response['$id'];}
|
||||
if(onProgress){onProgress(Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100);}}
|
||||
return response;}}),getFile:(bucketId,fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(onProgress){onProgress({$id:response.$id,progress:Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100,sizeUpploaded:end+1,chunksTotal:response.chunksTotal,chunksUploaded:response.chunksUploaded});}}
|
||||
return response;}),getFile:(bucketId,fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}',bucketId).replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(bucketId,fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
|
|
@ -3728,9 +3731,13 @@ if(forcePlaces!==false){rounded=Number(rounded).toFixed(forcePlaces);}
|
|||
return rounded+abbr;}
|
||||
window.ls.container.get("view").add({selector:"data-acl",controller:function(element,document,router,alerts){document.body.classList.remove("console");document.body.classList.remove("home");document.body.classList.add(router.getCurrent().view.scope);if(!router.getCurrent().view.project){document.body.classList.add("hide-nav");document.body.classList.remove("show-nav");}else{document.body.classList.add("show-nav");document.body.classList.remove("hide-nav");}
|
||||
if("/console"===router.getCurrent().path){document.body.classList.add("index");}else{document.body.classList.remove("index");}}}).add({selector:"data-prism",controller:function(window,document,element,alerts){Prism.highlightElement(element);let copy=document.createElement("i");copy.className="icon-docs copy";copy.title="Copy to Clipboard";copy.textContent="Click Here to Copy";copy.addEventListener("click",function(){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
|
||||
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{files:[],isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{this.files.forEach((file)=>{if(!file.completed&&!file.failed){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});});},toggle(){this.isOpen=!this.isOpen;},addFile(file){this.files.push(file);},updateFile(id,file){this.files=this.files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){this.files=this.files.filter((file)=>file.id!==id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const file=formData.get('file');const fileId=formData.get('fileId');const id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(read){read=JSON.parse(read);}
|
||||
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{_files:[],files(){return(this._files??[]).filter((file)=>!file.cancelled);},isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{this._files.forEach((file)=>{if(!file.completed&&!file.failed){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});});},cancelAll(){if(confirm("Are you sure? This will cancel and remove any ungoing uploads?")){this._files.forEach(file=>{if(file.completed||file.failed){this.removeFile(file.id);}else{this.updateFile(file.id,{cancelled:true});}});}},toggle(){this.isOpen=!this.isOpen;},addFile(file){this._files.push(file);},updateFile(id,file){this._files=this._files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){const file=this.getFile(id)??{};if(file.completed||file.failed){this._files=this._files.filter((file)=>file.id!==id);}else{if(confirm("Are you sure you want to cancel the upload?")){this.updateFile(id,{cancelled:true});}}},getFile(id){return this._files.find((file)=>file.id===id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const bucketId=formData.get('bucketId');const file=formData.get('file');const fileId=formData.get('fileId');let id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(!file||!fileId){return;}
|
||||
if(read){read=JSON.parse(read);}
|
||||
let write=formData.get('write');if(write){write=JSON.parse(wirte);}
|
||||
this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,isCancelled:false,});target.reset();try{const response=await sdk.storage.createFile(formData.get('bucketId'),fileId,file,read,write,(progress)=>{this.updateFile(id,{id:id,progress:Math.round(progress),});});this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){this.updateFile(id,{id:id,failed:true,});document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();}
|
||||
if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,});}
|
||||
target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,});}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();}
|
||||
throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},3000);};},redirect:function(url){return function(router){router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}else{return url;}}};keys=keys.split(",").map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split("=");let key=node[0]||"";let name=node[1]||key;let value=getValue(key,"param",serviceForm);url=updateQueryString(name,value?value:null,url);});if(url!==window.location.href){window.history.pushState({},"",url);router.reset();}};},trigger:function(events){return function(document){events=events.trim().split(",");for(let i=0;i<events.length;i++){if(""===events[i]){continue;}
|
||||
|
|
|
|||
17
public/dist/scripts/app-dep.js
vendored
17
public/dist/scripts/app-dep.js
vendored
|
|
@ -64,7 +64,8 @@ if(typeof scopes!=='undefined'){payload['scopes']=scopes;}
|
|||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
if(typeof window!=='undefined'&&(window===null||window===void 0?void 0:window.location)){window.location.href=uri.toString();}
|
||||
else{return uri;}},getSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createVerification:(url)=>__awaiter(this,void 0,void 0,function*(){if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/account/verification';let payload={};if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateVerification:(userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
|
|
@ -304,10 +305,10 @@ if(typeof code==='undefined'){throw new AppwriteException('Missing required para
|
|||
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof command!=='undefined'){payload['command']=command;}
|
||||
if(typeof code!=='undefined'){payload['code']=code;}
|
||||
const uri=new URL(this.config.endpoint+path);const size=code.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}
|
||||
else{let id=undefined;let response=undefined;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(let counter=0;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);const headers={'content-type':'multipart/form-data','content-range':'bytes '+start+'-'+end+'/'+size};if(id){headers['x-appwrite-id']=id;}
|
||||
let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(counter;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);headers['content-range']='bytes '+start+'-'+end+'/'+size;if(id){headers['x-appwrite-id']=id;}
|
||||
const stream=code.slice(start,end+1);payload['code']=new File([stream],code.name);response=yield this.call('post',uri,headers,payload);if(!id){id=response['$id'];}
|
||||
if(onProgress){onProgress(Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100);}}
|
||||
return response;}}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(onProgress){onProgress({$id:response.$id,progress:Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100,sizeUpploaded:end+1,chunksTotal:response.chunksTotal,chunksUploaded:response.chunksUploaded});}}
|
||||
return response;}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
|
|
@ -491,10 +492,12 @@ if(typeof file!=='undefined'){payload['file']=file;}
|
|||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
const uri=new URL(this.config.endpoint+path);const size=file.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}
|
||||
else{let id=undefined;let response=undefined;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(let counter=0;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);const headers={'content-type':'multipart/form-data','content-range':'bytes '+start+'-'+end+'/'+size};if(id){headers['x-appwrite-id']=id;}
|
||||
let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);if(fileId!='unique()'){try{response=yield this.call('GET',new URL(this.config.endpoint+path+'/'+fileId),headers);counter=response.chunksUploaded;}
|
||||
catch(e){}}
|
||||
for(counter;counter<totalCounters;counter++){const start=(counter*Appwrite.CHUNK_SIZE);const end=Math.min((((counter*Appwrite.CHUNK_SIZE)+Appwrite.CHUNK_SIZE)-1),size);headers['content-range']='bytes '+start+'-'+end+'/'+size;if(id){headers['x-appwrite-id']=id;}
|
||||
const stream=file.slice(start,end+1);payload['file']=new File([stream],file.name);response=yield this.call('post',uri,headers,payload);if(!id){id=response['$id'];}
|
||||
if(onProgress){onProgress(Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100);}}
|
||||
return response;}}),getFile:(bucketId,fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(onProgress){onProgress({$id:response.$id,progress:Math.min((counter+1)*Appwrite.CHUNK_SIZE,size)/size*100,sizeUpploaded:end+1,chunksTotal:response.chunksTotal,chunksUploaded:response.chunksUploaded});}}
|
||||
return response;}),getFile:(bucketId,fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}',bucketId).replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(bucketId,fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
|
|
|
|||
8
public/dist/scripts/app.js
vendored
8
public/dist/scripts/app.js
vendored
|
|
@ -689,9 +689,13 @@ if(forcePlaces!==false){rounded=Number(rounded).toFixed(forcePlaces);}
|
|||
return rounded+abbr;}
|
||||
window.ls.container.get("view").add({selector:"data-acl",controller:function(element,document,router,alerts){document.body.classList.remove("console");document.body.classList.remove("home");document.body.classList.add(router.getCurrent().view.scope);if(!router.getCurrent().view.project){document.body.classList.add("hide-nav");document.body.classList.remove("show-nav");}else{document.body.classList.add("show-nav");document.body.classList.remove("hide-nav");}
|
||||
if("/console"===router.getCurrent().path){document.body.classList.add("index");}else{document.body.classList.remove("index");}}}).add({selector:"data-prism",controller:function(window,document,element,alerts){Prism.highlightElement(element);let copy=document.createElement("i");copy.className="icon-docs copy";copy.title="Copy to Clipboard";copy.textContent="Click Here to Copy";copy.addEventListener("click",function(){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
|
||||
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{files:[],isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{this.files.forEach((file)=>{if(!file.completed&&!file.failed){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});});},toggle(){this.isOpen=!this.isOpen;},addFile(file){this.files.push(file);},updateFile(id,file){this.files=this.files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){this.files=this.files.filter((file)=>file.id!==id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const file=formData.get('file');const fileId=formData.get('fileId');const id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(read){read=JSON.parse(read);}
|
||||
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{_files:[],files(){return(this._files??[]).filter((file)=>!file.cancelled);},isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{this._files.forEach((file)=>{if(!file.completed&&!file.failed){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});});},cancelAll(){if(confirm("Are you sure? This will cancel and remove any ungoing uploads?")){this._files.forEach(file=>{if(file.completed||file.failed){this.removeFile(file.id);}else{this.updateFile(file.id,{cancelled:true});}});}},toggle(){this.isOpen=!this.isOpen;},addFile(file){this._files.push(file);},updateFile(id,file){this._files=this._files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){const file=this.getFile(id)??{};if(file.completed||file.failed){this._files=this._files.filter((file)=>file.id!==id);}else{if(confirm("Are you sure you want to cancel the upload?")){this.updateFile(id,{cancelled:true});}}},getFile(id){return this._files.find((file)=>file.id===id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const bucketId=formData.get('bucketId');const file=formData.get('file');const fileId=formData.get('fileId');let id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(!file||!fileId){return;}
|
||||
if(read){read=JSON.parse(read);}
|
||||
let write=formData.get('write');if(write){write=JSON.parse(wirte);}
|
||||
this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,isCancelled:false,});target.reset();try{const response=await sdk.storage.createFile(formData.get('bucketId'),fileId,file,read,write,(progress)=>{this.updateFile(id,{id:id,progress:Math.round(progress),});});this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){this.updateFile(id,{id:id,failed:true,});document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();}
|
||||
if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,});}
|
||||
target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,});}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();}
|
||||
throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},3000);};},redirect:function(url){return function(router){router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}else{return url;}}};keys=keys.split(",").map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split("=");let key=node[0]||"";let name=node[1]||key;let value=getValue(key,"param",serviceForm);url=updateQueryString(name,value?value:null,url);});if(url!==window.location.href){window.history.pushState({},"",url);router.reset();}};},trigger:function(events){return function(document){events=events.trim().split(",");for(let i=0;i<events.length;i++){if(""===events[i]){continue;}
|
||||
|
|
|
|||
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-rtl.css
vendored
2
public/dist/styles/default-rtl.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -764,6 +764,25 @@
|
|||
'content-type': 'application/json',
|
||||
}, payload);
|
||||
}),
|
||||
/**
|
||||
* Update Session (Refresh Tokens)
|
||||
*
|
||||
*
|
||||
* @param {string} sessionId
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateSession: (sessionId) => __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof sessionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "sessionId"');
|
||||
}
|
||||
let path = '/account/sessions/{sessionId}'.replace('{sessionId}', sessionId);
|
||||
let payload = {};
|
||||
const uri = new URL(this.config.endpoint + path);
|
||||
return yield this.call('patch', uri, {
|
||||
'content-type': 'application/json',
|
||||
}, payload);
|
||||
}),
|
||||
/**
|
||||
* Delete Account Session
|
||||
*
|
||||
|
|
@ -1463,9 +1482,9 @@
|
|||
* @param {string} collectionId
|
||||
* @param {string} key
|
||||
* @param {boolean} required
|
||||
* @param {string} min
|
||||
* @param {string} max
|
||||
* @param {string} xdefault
|
||||
* @param {number} min
|
||||
* @param {number} max
|
||||
* @param {number} xdefault
|
||||
* @param {boolean} array
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
|
|
@ -2561,32 +2580,37 @@
|
|||
'content-type': 'multipart/form-data',
|
||||
}, payload);
|
||||
}
|
||||
else {
|
||||
let id = undefined;
|
||||
let response = undefined;
|
||||
const totalCounters = Math.ceil(size / Appwrite.CHUNK_SIZE);
|
||||
for (let counter = 0; counter < totalCounters; counter++) {
|
||||
const start = (counter * Appwrite.CHUNK_SIZE);
|
||||
const end = Math.min((((counter * Appwrite.CHUNK_SIZE) + Appwrite.CHUNK_SIZE) - 1), size);
|
||||
const headers = {
|
||||
'content-type': 'multipart/form-data',
|
||||
'content-range': 'bytes ' + start + '-' + end + '/' + size
|
||||
};
|
||||
if (id) {
|
||||
headers['x-appwrite-id'] = id;
|
||||
}
|
||||
const stream = code.slice(start, end + 1);
|
||||
payload['code'] = new File([stream], code.name);
|
||||
response = yield this.call('post', uri, headers, payload);
|
||||
if (!id) {
|
||||
id = response['$id'];
|
||||
}
|
||||
if (onProgress) {
|
||||
onProgress(Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100);
|
||||
}
|
||||
let id = undefined;
|
||||
let response = undefined;
|
||||
const headers = {
|
||||
'content-type': 'multipart/form-data',
|
||||
};
|
||||
let counter = 0;
|
||||
const totalCounters = Math.ceil(size / Appwrite.CHUNK_SIZE);
|
||||
for (counter; counter < totalCounters; counter++) {
|
||||
const start = (counter * Appwrite.CHUNK_SIZE);
|
||||
const end = Math.min((((counter * Appwrite.CHUNK_SIZE) + Appwrite.CHUNK_SIZE) - 1), size);
|
||||
headers['content-range'] = 'bytes ' + start + '-' + end + '/' + size;
|
||||
if (id) {
|
||||
headers['x-appwrite-id'] = id;
|
||||
}
|
||||
const stream = code.slice(start, end + 1);
|
||||
payload['code'] = new File([stream], code.name);
|
||||
response = yield this.call('post', uri, headers, payload);
|
||||
if (!id) {
|
||||
id = response['$id'];
|
||||
}
|
||||
if (onProgress) {
|
||||
onProgress({
|
||||
$id: response.$id,
|
||||
progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100,
|
||||
sizeUpploaded: end + 1,
|
||||
chunksTotal: response.chunksTotal,
|
||||
chunksUploaded: response.chunksUploaded
|
||||
});
|
||||
}
|
||||
return response;
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
/**
|
||||
* Get Tag
|
||||
|
|
@ -4238,32 +4262,45 @@
|
|||
'content-type': 'multipart/form-data',
|
||||
}, payload);
|
||||
}
|
||||
else {
|
||||
let id = undefined;
|
||||
let response = undefined;
|
||||
const totalCounters = Math.ceil(size / Appwrite.CHUNK_SIZE);
|
||||
for (let counter = 0; counter < totalCounters; counter++) {
|
||||
const start = (counter * Appwrite.CHUNK_SIZE);
|
||||
const end = Math.min((((counter * Appwrite.CHUNK_SIZE) + Appwrite.CHUNK_SIZE) - 1), size);
|
||||
const headers = {
|
||||
'content-type': 'multipart/form-data',
|
||||
'content-range': 'bytes ' + start + '-' + end + '/' + size
|
||||
};
|
||||
if (id) {
|
||||
headers['x-appwrite-id'] = id;
|
||||
}
|
||||
const stream = file.slice(start, end + 1);
|
||||
payload['file'] = new File([stream], file.name);
|
||||
response = yield this.call('post', uri, headers, payload);
|
||||
if (!id) {
|
||||
id = response['$id'];
|
||||
}
|
||||
if (onProgress) {
|
||||
onProgress(Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100);
|
||||
}
|
||||
let id = undefined;
|
||||
let response = undefined;
|
||||
const headers = {
|
||||
'content-type': 'multipart/form-data',
|
||||
};
|
||||
let counter = 0;
|
||||
const totalCounters = Math.ceil(size / Appwrite.CHUNK_SIZE);
|
||||
if (fileId != 'unique()') {
|
||||
try {
|
||||
response = yield this.call('GET', new URL(this.config.endpoint + path + '/' + fileId), headers);
|
||||
counter = response.chunksUploaded;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
return response;
|
||||
}
|
||||
for (counter; counter < totalCounters; counter++) {
|
||||
const start = (counter * Appwrite.CHUNK_SIZE);
|
||||
const end = Math.min((((counter * Appwrite.CHUNK_SIZE) + Appwrite.CHUNK_SIZE) - 1), size);
|
||||
headers['content-range'] = 'bytes ' + start + '-' + end + '/' + size;
|
||||
if (id) {
|
||||
headers['x-appwrite-id'] = id;
|
||||
}
|
||||
const stream = file.slice(start, end + 1);
|
||||
payload['file'] = new File([stream], file.name);
|
||||
response = yield this.call('post', uri, headers, payload);
|
||||
if (!id) {
|
||||
id = response['$id'];
|
||||
}
|
||||
if (onProgress) {
|
||||
onProgress({
|
||||
$id: response.$id,
|
||||
progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100,
|
||||
sizeUpploaded: end + 1,
|
||||
chunksTotal: response.chunksTotal,
|
||||
chunksUploaded: response.chunksUploaded
|
||||
});
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
/**
|
||||
* Get File
|
||||
|
|
@ -4382,7 +4419,8 @@
|
|||
* Get a file preview image. Currently, this method supports preview for image
|
||||
* files (jpg, png, and gif), other supported formats, like pdf, docs, slides,
|
||||
* and spreadsheets, will return the file icon image. You can also pass query
|
||||
* string arguments for cutting and resizing your preview image.
|
||||
* string arguments for cutting and resizing your preview image. Preview is
|
||||
* supported only for image files smaller than 10MB.
|
||||
*
|
||||
* @param {string} bucketId
|
||||
* @param {string} fileId
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
(function(window){
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.store('uploader', {
|
||||
files: [],
|
||||
_files: [],
|
||||
files() {
|
||||
return (this._files ?? []).filter((file) => !file.cancelled);
|
||||
},
|
||||
isOpen: true,
|
||||
init() {
|
||||
window.addEventListener('beforeunload', (event) => {
|
||||
this.files.forEach((file) => {
|
||||
this._files.forEach((file) => {
|
||||
if(!file.completed && !file.failed) {
|
||||
let confirmationMessage = "There are incomplete uploads, are you sure you want to leave?";
|
||||
event.returnValue = confirmationMessage;
|
||||
|
|
@ -14,25 +17,50 @@
|
|||
});
|
||||
});
|
||||
},
|
||||
cancelAll() {
|
||||
if(confirm("Are you sure? This will cancel and remove any ungoing uploads?")){
|
||||
this._files.forEach(file => {
|
||||
if(file.completed || file.failed) {
|
||||
this.removeFile(file.id);
|
||||
} else {
|
||||
this.updateFile(file.id, {cancelled: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
toggle() {
|
||||
this.isOpen = !this.isOpen;
|
||||
},
|
||||
addFile(file) {
|
||||
this.files.push(file);
|
||||
this._files.push(file);
|
||||
},
|
||||
updateFile(id, file) {
|
||||
this.files = this.files.map((oldFile) => id == oldFile.id ? {...oldFile, ...file} : oldFile);
|
||||
this._files = this._files.map((oldFile) => id == oldFile.id ? {...oldFile, ...file} : oldFile);
|
||||
},
|
||||
removeFile(id) {
|
||||
this.files = this.files.filter((file) => file.id !== id);
|
||||
const file = this.getFile(id) ?? {};
|
||||
if(file.completed || file.failed) {
|
||||
this._files = this._files.filter((file) => file.id !== id);
|
||||
} else {
|
||||
if(confirm("Are you sure you want to cancel the upload?")) {
|
||||
this.updateFile(id, {cancelled: true});
|
||||
}
|
||||
}
|
||||
},
|
||||
getFile(id) {
|
||||
return this._files.find((file) => file.id === id);
|
||||
},
|
||||
async uploadFile(target) {
|
||||
const formData = new FormData(target);
|
||||
const sdk = window.ls.container.get('sdk');
|
||||
const bucketId = formData.get('bucketId');
|
||||
const file = formData.get('file');
|
||||
const fileId = formData.get('fileId');
|
||||
const id = fileId === 'unique()' ? performance.now() : fileId;
|
||||
let id = fileId === 'unique()' ? performance.now() : fileId;
|
||||
let read = formData.get('read');
|
||||
if(!file || !fileId) {
|
||||
return;
|
||||
}
|
||||
if(read) {
|
||||
read = JSON.parse(read);
|
||||
}
|
||||
|
|
@ -41,47 +69,78 @@
|
|||
write = JSON.parse(wirte);
|
||||
}
|
||||
|
||||
this.addFile({
|
||||
id: id,
|
||||
name: file.name,
|
||||
progress: 0,
|
||||
completed: false,
|
||||
failed: false,
|
||||
isCancelled: false,
|
||||
});
|
||||
if(this.getFile(id)) {
|
||||
this.updateFile(id, {
|
||||
name: file.name,
|
||||
completed: false,
|
||||
failed: false,
|
||||
cancelled: false,
|
||||
});
|
||||
} else {
|
||||
this.addFile({
|
||||
id: id,
|
||||
name: file.name,
|
||||
progress: 0,
|
||||
completed: false,
|
||||
failed: false,
|
||||
cancelled: false,
|
||||
});
|
||||
}
|
||||
|
||||
target.reset();
|
||||
try {
|
||||
const response = await sdk.storage.createFile(
|
||||
formData.get('bucketId'),
|
||||
bucketId,
|
||||
fileId,
|
||||
file,
|
||||
read,
|
||||
write,
|
||||
(progress) => {
|
||||
/*if cancelled
|
||||
throw something
|
||||
- When cancelled we need to delete the file
|
||||
- but we don't yet have the id of the file,
|
||||
- after resumable upload change, we will have the id
|
||||
*/
|
||||
this.updateFile(id, {
|
||||
id: id,
|
||||
progress: Math.round(progress),
|
||||
id: progress.$id,
|
||||
progress: Math.round(progress.progress),
|
||||
});
|
||||
id = progress.$id;
|
||||
|
||||
const file = this.getFile(id) ?? {};
|
||||
if(file.cancelled === true) {
|
||||
throw 'USER_CANCELLED';
|
||||
}
|
||||
});
|
||||
this.updateFile(id,{
|
||||
id: response.$id,
|
||||
name: response.name,
|
||||
progress: 100,
|
||||
completed: true,
|
||||
failed: false,
|
||||
});
|
||||
const existingFile = this.getFile(id) ?? {};
|
||||
if(existingFile.cancelled) {
|
||||
this.updateFile(id,{
|
||||
id: response.$id,
|
||||
name: response.name,
|
||||
failed: false,
|
||||
});
|
||||
id = response.$id;
|
||||
throw 'USER_CANCELLED'
|
||||
} else {
|
||||
this.updateFile(id,{
|
||||
id: response.$id,
|
||||
name: response.name,
|
||||
progress: 100,
|
||||
completed: true,
|
||||
failed: false,
|
||||
});
|
||||
id = response.$id;
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));
|
||||
} catch(error) {
|
||||
this.updateFile(id, {
|
||||
id: id,
|
||||
failed: true,
|
||||
});
|
||||
if(error === 'USER_CANCELLED') {
|
||||
await sdk.storage.deleteFile(bucketId, id);
|
||||
this.updateFile(id, {
|
||||
cancelled: false,
|
||||
failed: true,
|
||||
});
|
||||
this.removeFile(id);
|
||||
} else {
|
||||
this.updateFile(id, {
|
||||
id: id,
|
||||
failed: true,
|
||||
});
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,7 @@
|
|||
&.is-disabled { --p-pill-text-color:var(--config-disabled-color-hsl); }
|
||||
&.is-pending { --p-pill-text-color:var(--config-pending-color-hsl); }
|
||||
&.is-failed { --p-pill-text-color:var(--config-failed-color-hsl); }
|
||||
:root .theme-dark &{
|
||||
&.is-failed {color:#FFCFCF; background-color:#B91C1C;}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,21 +31,22 @@
|
|||
}
|
||||
&-content {
|
||||
background-color:var(--p-content-bg-color); color:var(--p-content-text-color);
|
||||
height:0; overflow:hidden;
|
||||
height:0; overflow:auto;
|
||||
transition:var(--transition);
|
||||
&.is-open {height:200px; /* consider to change to rem */}
|
||||
}
|
||||
&-list {}
|
||||
&-item {
|
||||
display:flex; padding:13px 20px;
|
||||
.file-name { @include trim; align-self:center; margin-inline-end:auto; }
|
||||
display:flex; align-items:center; padding:13px 20px;
|
||||
.file-name {text-overflow:ellipsis; white-space:nowrap; overflow:hidden; align-self:center; margin-inline-end:auto; line-height:normal; }
|
||||
.icon-button{ align-self:center; margin-inline-start:16px;}
|
||||
.pill{margin-inline-start:8px;}
|
||||
&:not(:last-child) { border-bottom:solid 1px var(--p-border-color); }
|
||||
}
|
||||
|
||||
/* responsive */
|
||||
@media @phones { inset-inline:16px; inset-block-end:20px; }
|
||||
@media @tablets, @desktops { inset-inline-end:24px; inset-block-end:24px; }
|
||||
@media @tablets, @desktops { max-width:285px; inset-inline-end:24px; inset-block-end:24px; }
|
||||
|
||||
/* dark theme */
|
||||
:root .theme-dark &{
|
||||
|
|
@ -58,9 +59,9 @@
|
|||
@upload-image-size-default: 40px;
|
||||
--p-upload-image-size:var(--upload-image-size, @upload-image-size-default);
|
||||
--p-upload-bg-color:var(--config-color-fade-super);
|
||||
--p-upload-icon-color:var(--config-color-fade-light);
|
||||
--p-upload-icon-color:var(--config-color-fade);
|
||||
|
||||
position:relative; display:grid; place-content:center;
|
||||
position:relative; display:grid; place-content:center; flex-shrink:0;
|
||||
width:var(--p-upload-image-size);
|
||||
height:var(--p-upload-image-size);
|
||||
background-color:var(--p-upload-bg-color);
|
||||
|
|
@ -86,7 +87,6 @@
|
|||
hsl(var(--zero-value)) 100%)";
|
||||
}
|
||||
&.is-finished {
|
||||
--p-upload-icon-color:var(--config-color-fade);
|
||||
.progress{ display:none; }
|
||||
}
|
||||
/* dark theme */
|
||||
|
|
|
|||
Loading…
Reference in a new issue