Basic download logic finished

- Added download progress UI
- Added download finished
This commit is contained in:
2024-02-18 00:13:44 +01:00
parent c084af461f
commit 7f742dac63
3 changed files with 112 additions and 20 deletions

View File

@ -1,25 +1,66 @@
<div class="container mx-auto p-4 mt-4 animate-in fade-in slide-in-from-left-6 duration-300">
<h1 class="text-4xl font-bold text-center text-gray-800 mb-2">Download File</h1>
<p class="text-md text-center text-gray-600 mb-6">Access your files quickly and securely</p>
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
<img class="w-56 mt-6 mb-6" src="./assets/cloud-arrow-down-solid.svg">
<input type="text" class="input input-bordered text-center w-full max-w-md mb-6" placeholder="Enter download code/link" [(ngModel)]="inputFileId"/>
<input
*ngIf="downloadInfo && downloadInfo.passwordProtected && downloadInfo.downloadable"
type="password" class="input input-bordered text-center w-full max-w-md mb-6" placeholder="Enter file password..." [(ngModel)]="filePassword"/>
<div
*ngIf="!fileDownloadStarted && !fileDownloadFinished"
>
<p class="text-md text-center text-gray-600 mb-6">Access your files quickly and securely</p>
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
<img class="w-56 mt-6 mb-6" src="./assets/cloud-arrow-down-solid.svg">
<input type="text" class="input input-bordered text-center w-full max-w-md mb-6" placeholder="Enter download code/link" [(ngModel)]="inputFileId"/>
<input
*ngIf="downloadInfo && downloadInfo.passwordProtected && downloadInfo.downloadable"
type="password" class="input input-bordered text-center w-full max-w-md mb-6" placeholder="Enter file password..." [(ngModel)]="filePassword"/>
<button class="btn btn-primary w-full max-w-md flex justify-center items-center mb-4" (click)="requestDownload()">
Download
</button>
<button
(click)="download_not_possible.showModal()"
class="btn btn-secondary btn-outline w-full max-w-md flex justify-center items-center mb-4">
Reset
</button>
<p class="text-gray-600 text-center w-2/3">Files are available for a limited time. Ensure the code or link is correct and the file is still downloadable.</p>
<button class="btn btn-primary w-full max-w-md flex justify-center items-center mb-4" (click)="requestDownload()">
Download
</button>
<button
(click)="download_not_possible.showModal()"
class="btn btn-secondary btn-outline w-full max-w-md flex justify-center items-center mb-4">
Reset
</button>
<p class="text-gray-600 text-center w-2/3">Files are available for a limited time. Ensure the code or link is correct and the file is still downloadable.</p>
</div>
</div>
<div
*ngIf="fileDownloadStarted && !fileDownloadFinished"
>
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
<div class="radial-progress mb-6" [style.--value]="downloadProgress" style="--size:12rem; --thickness: 2rem;" role="progressbar">{{ downloadProgress | number:'1.0-0' }}%</div>
<h3 class="text-xl font-bold text-center text-gray-800 mb-2">Downloading...</h3>
<p class="text-gray-600 text-center w-2/3 mb-6">Your file is being downloaded in the background. Please wait...</p>
<p class="text-gray-600 text-center w-2/3 mb-6">{{ downloadDuration }} seconds passed.</p>
</div>
</div>
<div
*ngIf="fileDownloadFinished"
>
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
<img class="w-16 mb-6" src="./assets/circle-check-solid.svg" alt="Success">
<p class="text-xl font-bold text-center text-gray-800 mb-6">Download complete!</p>
<p class="text-gray-600 text-center w-2/3 mb-3">File {{ fileName }} has been downloaded and saved to your drive.</p>
<p class="text-gray-600 text-center w-2/3 mb-6">The download took {{ downloadDuration }} seconds.</p>
<button class="btn btn-primary w-full max-w-md flex justify-center items-center mb-4" >
Save to disk (again)
</button>
<button class="btn btn-primary w-full max-w-md flex justify-center items-center mb-4" routerLink="/home">
Back to home
</button>
</div>
</div>
</div>
<div class="flex flex-col items-center justify-center">
<div *ngIf="fileDownloadStarted && !fileDownloadFinished" class="card w-96 bg-base-100 shadow-xl">
<div class="card-body flex flex-col items-center justify-center">
<h2 class="card-title text-center">Did you know?</h2>
<p class="text-center">{{ funfact }}</p>
</div>
</div>
</div>
<dialog #download_not_possible class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">The file cant be downloaded!</h3>
@ -41,3 +82,6 @@
<button>close</button>
</form>
</dialog>
<div class="invisible h-0 w-0">
<img src="./assets/circle-check-solid.svg">
</div>

View File

@ -2,14 +2,18 @@ import {Component, ElementRef, ViewChild} from '@angular/core';
import axios from "axios";
import {DevelopmentStore} from "../../store/DevelopmentStore";
import {FormsModule} from "@angular/forms";
import {NgIf} from "@angular/common";
import {DecimalPipe, NgIf} from "@angular/common";
import funfacts from "../../assets/funfacts";
import {RouterLink} from "@angular/router";
@Component({
selector: 'app-download',
standalone: true,
imports: [
FormsModule,
NgIf
NgIf,
DecimalPipe,
RouterLink
],
templateUrl: './download.component.html',
styleUrl: './download.component.scss'
@ -18,15 +22,23 @@ export class DownloadComponent {
@ViewChild('download_not_possible') download_not_possible: ElementRef<HTMLDialogElement> | undefined;
inputFileId: string = "";
inputFileId: string = "2402171";
fileId: string = "";
filePassword: string = "";
fileName: string = "";
downloadInfo: DownloadInfo | null = null;
fileDownloadStarted: boolean = false;
fileDownloadFinished: boolean = false;
waitingForPassword: boolean = false;
downloadProgress: number = 0;
downloadDuration: string = "";
funfact: string = "";
constructor(private developmentStore: DevelopmentStore) {
this.funfact = funfacts[Math.floor(Math.random() * funfacts.length)];
this.speedTest();
}
@ -98,6 +110,8 @@ export class DownloadComponent {
}
private downloadFile() {
const startTime = new Date().getTime();
this.fileDownloadStarted = true;
axios({
method: 'get',
url: this.developmentStore.getBaseUrl() + 'api/v1/download?fileId=' + this.fileId,
@ -105,15 +119,24 @@ export class DownloadComponent {
headers: {
'Access-Control-Allow-Origin': '*', // Allow CORS
},
onDownloadProgress: function(progressEvent) {
onDownloadProgress: (progressEvent) => {
const endTime = new Date().getTime();
const duration = (endTime - startTime) / 1000;
this.downloadDuration = duration.toFixed(0);
// Calculate the percentage of download completed
if(progressEvent.total) {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
this.downloadProgress = percentCompleted;
console.log(percentCompleted + '%'); // Log the percentage or update any progress UI component
}
}
})
.then(response => {
const endTime = new Date().getTime();
const duration = (endTime - startTime) / 1000;
this.downloadDuration = duration.toFixed(2);
this.fileDownloadFinished = true;
const contentDisposition = response.headers['content-disposition'];
let filename = "default_filename"; // Default filename in case parsing fails
@ -124,6 +147,7 @@ export class DownloadComponent {
filename = matches[1];
}
}
this.fileName = filename;
const blob = new Blob([response.data], {type: 'application/octet-stream'});
const url = window.URL.createObjectURL(blob);