Files
AstroJS/botanjs/src/Astro/Blog/AstroEdit/Uploader.js
T
2026-06-12 04:52:10 +08:00

242 lines
5.8 KiB
JavaScript

(function( ){
var ns = __namespace( "Astro.Blog.AstroEdit" );
/** @type {System.Cycle} */
var Cycle = __import( "System.Cycle" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {System.utils.EventKey} */
var EventKey = __import( "System.utils.EventKey" );
/** @type {Components.Mouse.ContextMenu} */
var ContextMenu = __import( "Components.Mouse.ContextMenu" );
/** @type {typeof Dandelion} */
var Dand = __import( "Dandelion" );
/** @type {Dandelion.IDOMObject} */
var IDOMObject = __import( "Dandelion.IDOMObject" );
/** @type {Astro.Blog.Config} */
var Conf = __import( "Astro.Blog.Config" );
/** @type {System.utils.Perf} */
var Perf = __import( "System.utils.Perf" );
var postFile = __import( "System.Net.postFile" );
var Uploader = function ( set_file_uri )
{
/** @type {_AstConf_.SiteFile} */
var config = Conf.get( "SiteFile" );
// linkage
var busy = false
, placedFiles = []
, currentFile
// Prepare structure for dockpanel
, ptext = Dand.id( "asl_ptext" )
, pbar = Dand.id( "asl_pbar_fill" )
, ppreview = Dand.id( "asl_preview" )
, pfileName = Dand.id( "asl_fileName" )
, instruction = Dand.id( "asl_instruction" )
, p_status = Dand.id( "asl_u_head" )
, fileList = Dand.id( "asl_fileList" )
, stage = Dand.id( "asl_uploader" )
, uploadProgress = function(e)
{
var done = e.position || e.loaded
, total = e.totalSize || e.total
, percentage = String( Math.floor( done / total * 1000 )/10 ) + "%";
// Set progress
ptext.innetText
= ptext.textContent
= pbar.style.width
= percentage;
}
, uploadComplete = function ( response )
{
try
{
var obj = JSON.parse( response );
if(obj.status)
{
currentFile.setStatus( "ok", config.f_host + obj.destination );
}
else
{
currentFile.setStatus( "error", obj.message );
}
new ContextMenu( currentFile.stage, currentFile.menuKeys, "LMB", stage );
}
catch ( ex )
{
currentFile.setStatus( "error", ex.message );
debug.Error( ex );
}
beginUpload();
}
, beginUpload = function()
{
busy = true;
if( placedFiles.length )
{
currentFile = placedFiles.pop();
if( currentFile )
{
var file = currentFile.file;
pfileName.textContent = pfileName.innetText = file.name;
var fd = new FormData();
fd.append( "uploadFile", file );
postFile( set_file_uri, fd, { progress: uploadProgress, complete: uploadComplete } );
currentFile.setStatus("active");
instruction.style.marginTop = "-80px";
}
else
{
// deleted file, skip it
beginUpload();
}
}
else
{
busy = false;
instruction.style.marginTop = "";
}
}
, clearFileList = function ()
{
while( fileList.hasChildNodes() )
{
fileList.removeChild( fileList.firstChild );
}
}
, retryUpload = function ()
{
this.setStatus("pending");
placedFiles[placedFiles.length] = this;
new ContextMenu( this.stage, this.menuKeys, "RMB", stage );
if( !busy ) beginUpload();
}
, removeItem = function ()
{
this.stage.style.marginTop = "-2em";
this.stage.style.opacity = "0";
if( placedFiles.indexOf(this) != -1 )
{
delete placedFiles[placedFiles.indexOf(this)];
}
Cycle.delay(function () {
fileList.removeChild(this);
}.bind(this.stage), 250);
}
;
fileList.style.paddingTop = String(p_status.clientHeight) + "px";
var docDom = IDOMObject( document );
// Drag/drop handlers
docDom.addEventListener( "DragOver", function ( e )
{
e.preventDefault();
this.className = "dragged_over";
} );
docDom.addEventListener( "DragEnd", function () { this.className = ""; } );
docDom.addEventListener( "Drop", function ( e )
{
e.preventDefault();
this.className = "";
// Push files
var list = e.dataTransfer.files;
for(var i in list)
{
if(list[i].type != undefined)
{
var fileItem = new ASLFileItem(list[i], {clear: clearFileList, remove: removeItem, retry: retryUpload});
placedFiles[placedFiles.length] = fileItem;
fileList.appendChild(fileItem.stage);
new ContextMenu(fileItem.stage, fileItem.menuKeys, "LMB", stage);
}
}
if(!busy) beginUpload();
return false;
} );
};
var ASLFileItem = function (file, callbacks)
{
var statusblob = Dand.wrap("span", null, "asl_uItemStat", "\u25CF")
, msg
, _items = [
new EventKey("Remove this item", callbacks.remove.bind(this)) // Reserved for remove item
, null // Reserved for retry/ Open link
, null // Reserved for get Error message
, new EventKey("Clear all", callbacks.clear)
]
, popMessage = function ()
{
new MessageBox("Upload error", msg).show();
}
, getFileLink = function ()
{
return msg;
}
;
this.stage = Dand.wrap( null, "asl_item" + Perf.uuid, "asl_uItem", [ statusblob, Dand.textNode(file.name) ] );
this.file = file;
this.menuKeys = _items;
this.setStatus = function (st, message)
{
msg = message;
switch(st)
{
case "active":
statusblob.style.color = "cornflowerblue";
break;
case "error":
statusblob.style.color = "red";
_items[1] = new EventKey( "Retry", callbacks.retry.bind(this) );
_items[2] = new EventKey( "Whats wrong ?", popMessage );
break;
case "ok":
statusblob.style.color = "greenyellow";
_items[1] = new EventKey( "Copy file link", getFileLink );
break;
default:// pending
delete _items[1];
delete _items[2];
statusblob.style.color = "";
}
}
};
ns[ NS_EXPORT ]( EX_CLASS, "Uploader", Uploader );
})();