Basic download logic finished
- Added download progress UI - Added download finished
This commit is contained in:
parent
c084af461f
commit
7f742dac63
@ -1,25 +1,66 @@
|
|||||||
<div class="container mx-auto p-4 mt-4 animate-in fade-in slide-in-from-left-6 duration-300">
|
<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>
|
<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
|
||||||
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
|
*ngIf="!fileDownloadStarted && !fileDownloadFinished"
|
||||||
<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"/>
|
<p class="text-md text-center text-gray-600 mb-6">Access your files quickly and securely</p>
|
||||||
<input
|
<div class="bg-white shadow-lg rounded-lg p-6 flex flex-col items-center justify-center">
|
||||||
*ngIf="downloadInfo && downloadInfo.passwordProtected && downloadInfo.downloadable"
|
<img class="w-56 mt-6 mb-6" src="./assets/cloud-arrow-down-solid.svg">
|
||||||
type="password" class="input input-bordered text-center w-full max-w-md mb-6" placeholder="Enter file password..." [(ngModel)]="filePassword"/>
|
<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()">
|
<button class="btn btn-primary w-full max-w-md flex justify-center items-center mb-4" (click)="requestDownload()">
|
||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
(click)="download_not_possible.showModal()"
|
(click)="download_not_possible.showModal()"
|
||||||
class="btn btn-secondary btn-outline w-full max-w-md flex justify-center items-center mb-4">
|
class="btn btn-secondary btn-outline w-full max-w-md flex justify-center items-center mb-4">
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</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>
|
<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>
|
</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">
|
<dialog #download_not_possible class="modal">
|
||||||
<div class="modal-box">
|
<div class="modal-box">
|
||||||
<h3 class="font-bold text-lg">The file cant be downloaded!</h3>
|
<h3 class="font-bold text-lg">The file cant be downloaded!</h3>
|
||||||
@ -41,3 +82,6 @@
|
|||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
<div class="invisible h-0 w-0">
|
||||||
|
<img src="./assets/circle-check-solid.svg">
|
||||||
|
</div>
|
||||||
|
@ -2,14 +2,18 @@ import {Component, ElementRef, ViewChild} from '@angular/core';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {DevelopmentStore} from "../../store/DevelopmentStore";
|
import {DevelopmentStore} from "../../store/DevelopmentStore";
|
||||||
import {FormsModule} from "@angular/forms";
|
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({
|
@Component({
|
||||||
selector: 'app-download',
|
selector: 'app-download',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NgIf
|
NgIf,
|
||||||
|
DecimalPipe,
|
||||||
|
RouterLink
|
||||||
],
|
],
|
||||||
templateUrl: './download.component.html',
|
templateUrl: './download.component.html',
|
||||||
styleUrl: './download.component.scss'
|
styleUrl: './download.component.scss'
|
||||||
@ -18,15 +22,23 @@ export class DownloadComponent {
|
|||||||
|
|
||||||
@ViewChild('download_not_possible') download_not_possible: ElementRef<HTMLDialogElement> | undefined;
|
@ViewChild('download_not_possible') download_not_possible: ElementRef<HTMLDialogElement> | undefined;
|
||||||
|
|
||||||
inputFileId: string = "";
|
inputFileId: string = "2402171";
|
||||||
fileId: string = "";
|
fileId: string = "";
|
||||||
filePassword: string = "";
|
filePassword: string = "";
|
||||||
|
fileName: string = "";
|
||||||
downloadInfo: DownloadInfo | null = null;
|
downloadInfo: DownloadInfo | null = null;
|
||||||
|
|
||||||
|
fileDownloadStarted: boolean = false;
|
||||||
|
fileDownloadFinished: boolean = false;
|
||||||
waitingForPassword: boolean = false;
|
waitingForPassword: boolean = false;
|
||||||
|
downloadProgress: number = 0;
|
||||||
|
downloadDuration: string = "";
|
||||||
|
|
||||||
|
funfact: string = "";
|
||||||
|
|
||||||
|
|
||||||
constructor(private developmentStore: DevelopmentStore) {
|
constructor(private developmentStore: DevelopmentStore) {
|
||||||
|
this.funfact = funfacts[Math.floor(Math.random() * funfacts.length)];
|
||||||
this.speedTest();
|
this.speedTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +110,8 @@ export class DownloadComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private downloadFile() {
|
private downloadFile() {
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
this.fileDownloadStarted = true;
|
||||||
axios({
|
axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: this.developmentStore.getBaseUrl() + 'api/v1/download?fileId=' + this.fileId,
|
url: this.developmentStore.getBaseUrl() + 'api/v1/download?fileId=' + this.fileId,
|
||||||
@ -105,15 +119,24 @@ export class DownloadComponent {
|
|||||||
headers: {
|
headers: {
|
||||||
'Access-Control-Allow-Origin': '*', // Allow CORS
|
'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
|
// Calculate the percentage of download completed
|
||||||
if(progressEvent.total) {
|
if(progressEvent.total) {
|
||||||
const percentCompleted = Math.round((progressEvent.loaded * 100) / 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
|
console.log(percentCompleted + '%'); // Log the percentage or update any progress UI component
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(response => {
|
.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'];
|
const contentDisposition = response.headers['content-disposition'];
|
||||||
let filename = "default_filename"; // Default filename in case parsing fails
|
let filename = "default_filename"; // Default filename in case parsing fails
|
||||||
|
|
||||||
@ -124,6 +147,7 @@ export class DownloadComponent {
|
|||||||
filename = matches[1];
|
filename = matches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.fileName = filename;
|
||||||
|
|
||||||
const blob = new Blob([response.data], {type: 'application/octet-stream'});
|
const blob = new Blob([response.data], {type: 'application/octet-stream'});
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
24
frontend/src/assets/funfacts.ts
Normal file
24
frontend/src/assets/funfacts.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
let funfacts = [
|
||||||
|
"Honey never spoils. Archaeologists have found pots of honey in ancient Egyptian tombs that are over 3,000 years old and still edible.",
|
||||||
|
"Octopuses have three hearts and blue blood.",
|
||||||
|
"Bananas are berries, but strawberries are not.",
|
||||||
|
"The shortest war in history was between Britain and Zanzibar on August 27, 1896. Zanzibar surrendered after 38 minutes.",
|
||||||
|
"A day on Venus is longer than a year on Venus.",
|
||||||
|
"The Eiffel Tower can be 15 cm taller during the summer when the iron heats up and expands.",
|
||||||
|
"Cows have best friends and can become stressed if they are separated.",
|
||||||
|
"A group of flamingos is called a flamboyance.",
|
||||||
|
"The unicorn is the national animal of Scotland.",
|
||||||
|
"More people are killed each year by cows than by sharks.",
|
||||||
|
"The total weight of all the ants on Earth is about the same as the weight of all the humans on Earth.",
|
||||||
|
"Wombat poop is cube-shaped.",
|
||||||
|
"The inventor of the frisbee was turned into a frisbee after he died.",
|
||||||
|
"There are more possible iterations of a game of chess than there are atoms in the known universe.",
|
||||||
|
"The heart of a blue whale is so large that a human can swim through the arteries.",
|
||||||
|
"Vending machines kill 4 times as many people as sharks per year.",
|
||||||
|
"Butterflies taste with their feet.",
|
||||||
|
"In Switzerland, it is illegal to own just one guinea pig because they are prone to loneliness.",
|
||||||
|
"Snails can sleep for up to three years.",
|
||||||
|
"The old Twitter bird actually had a name - Larry."
|
||||||
|
];
|
||||||
|
export default funfacts;
|
Loading…
x
Reference in New Issue
Block a user