<%@ Page Title="Large File Upload" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Large File Upload - AjaxUploader v5.2 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Large File Upload</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Large File Upload (1 GB+)</div> <div class="demo-card-body"> <p class="demo-description"> Optimized configuration for uploading very large files. Uses larger chunk sizes, parallel
 chunk uploads, and automatic retry to ensure reliable delivery of files over 1 GB.
 </p> <au:AjaxFileUpload ID="Uploader1" runat="server"
 EnableChunkedUpload="true"
 ChunkSize="10485760"
 ParallelChunks="3"
 MaxRetries="5"
 MaxFileSize="5368709120" /> <div class="mt-3"> <div class="progress" style="height:24px;"> <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated"
 role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="width:0%">0%</div> </div> <div class="d-flex justify-content-between mt-1 small text-muted"> <span id="uploaded">Uploaded: 0 B</span> <span id="speed">Speed: --</span> <span id="remaining">ETA: --</span> </div> </div> <div class="code-panel"> <pre><code>&lt;au:AjaxFileUpload ID="Uploader1" runat="server"
 EnableChunkedUpload="true"
 ChunkSize="10485760"
 ParallelChunks="3"
 MaxRetries="5"
 MaxFileSize="5368709120" /&gt;

// JavaScript API approach
AjaxUploader.create('#uploader', {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 chunkUrl: '<%= ResolveUrl("~/ajaxupload.axd/chunk") %>',
 chunked: true,
 chunkSize: 10 * 1024 * 1024, // 10 MB chunks
 concurrency: 3,
 retries: 5,
 maxFileSize: 5 * 1024 * 1024 * 1024, // 5 GB limit
 onTaskProgress: function(task) {
 // Update progress bar, speed, and ETA
 }
});</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> var bar = document.getElementById('progressBar');
 var uploaded = document.getElementById('uploaded');
 var speed = document.getElementById('speed');
 var remaining = document.getElementById('remaining');
 function clampPercent(value) {
 var pct = Number(value);
 if (!isFinite(pct)) return 0;
 return Math.max(0, Math.min(100, Math.round(pct)));
 }

 var uploader = window.AjaxUploader && AjaxUploader.getInstance ? AjaxUploader.getInstance('Uploader1') : null;
 if (uploader) {
 uploader.on('taskProgress', function(task) {
 var pct = clampPercent(task.percent);
 if (bar) {
 bar.style.width = pct + '%';
 bar.setAttribute('aria-valuenow', pct);
 bar.textContent = pct + '%';
 }
 if (uploaded && window.AjaxUploader && AjaxUploader.formatSize) {
 uploaded.textContent = 'Uploaded: ' + AjaxUploader.formatSize(task.loaded) +
 ' / ' + AjaxUploader.formatSize(task.total);
 }
 if (speed && window.AjaxUploader && AjaxUploader.formatSize) {
 speed.textContent = 'Speed: ' + AjaxUploader.formatSize(task.speed) + '/s';
 }
 if (remaining && task.speed > 0 && window.AjaxUploader && AjaxUploader.formatTime) {
 var eta = (task.total - task.loaded) / task.speed;
 remaining.textContent = 'ETA: ' + AjaxUploader.formatTime(eta);
 }
 });
 uploader.on('taskComplete', function(task) {
 if (bar) {
 bar.setAttribute('aria-valuenow', 100);
 bar.classList.remove('progress-bar-animated');
 bar.classList.add('bg-success');
 bar.textContent = 'Complete';
 }
 if (speed) {
 speed.textContent = '';
 }
 if (remaining) {
 remaining.textContent = '';
 }
 });
 uploader.on('taskError', function(task, err) {
 if (bar) {
 bar.setAttribute('aria-valuenow', 0);
 bar.classList.remove('progress-bar-animated');
 bar.classList.add('bg-danger');
 bar.textContent = 'Error';
 }
 });
 }
</script>
</asp:Content>
