<%@ Page Title="Resume Upload" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Resume Upload - AjaxUploader v5.3 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Resume Upload</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Resume Upload After Interruption</div> <div class="demo-card-body"> <p class="demo-description"> Chunked uploads can be resumed after a network interruption or browser close. The server
 tracks which chunks have been received so only the remaining chunks are uploaded on retry.
 </p>
 <div class="demo-expect"><strong>What you should see:</strong> start a large upload, refresh the page mid-transfer, and the queue restores and continues from the last completed chunk instead of restarting at 0%.</div> <au:AjaxFileUpload ID="Uploader1" runat="server"
 EnableChunkedUpload="true"
 EnableResume="true"
 ChunkSize="1048576"
 AutoUpload="true" /> <div class="mt-3"> <button type="button" class="btn btn-warning btn-sm" id="btnSimulate" disabled>Simulate Interruption</button> <button type="button" class="btn btn-success btn-sm" id="btnResume" disabled>Resume Upload</button> </div> <div id="log" class="mt-3 p-2 bg-light border rounded" style="max-height:180px;overflow-y:auto;font-size:.85rem;"></div> <div class="code-panel"> <pre><code>&lt;au:AjaxFileUpload ID="Uploader1" runat="server"
 EnableChunkedUpload="true"
 EnableResume="true"
 ChunkSize="1048576"
 AutoUpload="true" /&gt;

// JavaScript API approach
var uploader = AjaxUploader.create('#uploader', {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 chunkUrl: '<%= ResolveUrl("~/ajaxupload.axd/chunk") %>',
 chunkCompleteUrl: '<%= ResolveUrl("~/ajaxupload.axd/chunk/complete") %>',
 chunked: true,
 chunkSize: 1 * 1024 * 1024,
 autoUpload: true,
 onTaskError: function(task, error) {
 log('Interrupted: ' + task.fileName + ' - can resume from chunk ' + task.chunkIndex);
 }
});

// Resume: uploader.retryTask(taskId);</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> var logEl = document.getElementById('log');
 var btnSimulate = document.getElementById('btnSimulate');
 var btnResume = document.getElementById('btnResume');
 var currentTaskId = null;

 function log(msg) {
 var div = document.createElement('div');
 div.textContent = '[' + new Date().toLocaleTimeString() + '] ' + msg;
 logEl.appendChild(div);
 logEl.scrollTop = logEl.scrollHeight;
 }

 var uploader = AjaxUploader.getInstance('Uploader1');
 if (uploader) {
 uploader.on('taskStart', function(task) {
 currentTaskId = task.id;
 btnSimulate.disabled = false;
 log('Started: ' + task.fileName);
 });
 uploader.on('taskProgress', function(task) {
 log('Progress: ' + task.fileName + ' ' + Math.round(task.percent) + '%');
 });
 uploader.on('taskError', function(task, error) {
 log('Interrupted: ' + task.fileName);
 btnResume.disabled = false;
 btnSimulate.disabled = true;
 });
 uploader.on('taskComplete', function(task) {
 log('Completed: ' + task.fileName);
 btnSimulate.disabled = true;
 btnResume.disabled = true;
 });
 }

 btnSimulate.addEventListener('click', function() {
 if (currentTaskId && uploader) {
 uploader.pauseTask(currentTaskId);
 log('Upload paused - simulating network interruption.');
 btnResume.disabled = false;
 btnSimulate.disabled = true;
 }
 });

 btnResume.addEventListener('click', function() {
 if (currentTaskId && uploader) {
 uploader.retryTask(currentTaskId);
 log('Resuming upload...');
 btnResume.disabled = true;
 btnSimulate.disabled = false;
 }
 });
</script>
</asp:Content>
