src/app/app.component.ts
Class AppComponent is our main angular component to upload and preview "text files, PDFs, images" and preview
selector | app-root |
styleUrls | ./app.component.scss |
templateUrl | ./app.component.html |
Properties |
Methods |
constructor(modalService: NgbModal, storage: AngularFireStorage)
|
|||||||||
Defined in src/app/app.component.ts:76
|
|||||||||
We just define NgbModal,AngularFireStorage in the constructor
Parameters :
|
Async createThumb | ||||||||||
createThumb(contentType, name, url, obj)
|
||||||||||
Defined in src/app/app.component.ts:141
|
||||||||||
Add Thumb to the file "Thumb will be the same as photo source in case of images or generated from pdf first page or placeholder for txt files.
Parameters :
Returns :
any
|
logSlide | ||||||
logSlide(ev: any)
|
||||||
Defined in src/app/app.component.ts:194
|
||||||
update the active slide ID from the modal.
Parameters :
Returns :
void
|
open |
open(content: any, slide: string)
|
Defined in src/app/app.component.ts:200
|
Open ngbootstrap modal with current slide activated and add specific class modal-reader to the modal.
Returns :
void
|
pondHandleInit |
pondHandleInit()
|
Defined in src/app/app.component.ts:162
|
This Event fires after filepond initialized then we can add to it the files comes from the server.
Returns :
void
|
pondHandleProcessFile | ||||||
pondHandleProcessFile(event: any)
|
||||||
Defined in src/app/app.component.ts:174
|
||||||
This Event fires after file uploaded successfuly so we can push this file to our files array to be displayed.
Parameters :
Returns :
void
|
pondHandleRemoveFile | ||||||
pondHandleRemoveFile(event: any)
|
||||||
Defined in src/app/app.component.ts:180
|
||||||
This Event fires after file removedfrom filepond so we can delete this file from our files array to not be displayed.
Parameters :
Returns :
void
|
Async pushFile | ||||
pushFile(file)
|
||||
Defined in src/app/app.component.ts:125
|
||||
Read data from filepond file instance and create object and push it to our files array.
Parameters :
Returns :
any
|
Async pushPondFiles | ||||
pushPondFiles(files)
|
||||
Defined in src/app/app.component.ts:87
|
||||
Add files "returnced from the serve" to filepond component.
Parameters :
Returns :
any
|
removeFile | ||||
removeFile(id)
|
||||
Defined in src/app/app.component.ts:153
|
||||
Remove file from filepond and hence trigger pondHandleRemoveFile which will remove it from the thumbnails list.
Parameters :
Returns :
void
|
activeId |
Type : string
|
Defined in src/app/app.component.ts:18
|
activeId property to be used for the carousel as a current slide id |
filePond |
Type : any
|
Decorators :
@ViewChild('filePond')
|
Defined in src/app/app.component.ts:20
|
declare filePond as filepond instance |
files |
Type : any[]
|
Default value : []
|
Defined in src/app/app.component.ts:16
|
files property to be our files array to be binded and displayed |
pondOptions |
Type : object
|
Default value : {
labelIdle: "Drop file here",
allowMultiple: true,
allowFileRename: true,
fileRenameFunction: file => {
return file.name.replace(/[&\/\\#,+()$~%'":*?<>{}]/g, "");
},
server: {
process: (fieldName, file, metadata, load, error, progress, abort) => {
const path = `files/${new Date().getTime()}_${file.name}`;
file.id = Utils.uniqueId();
const uploadTask = this.storage.upload(path, file);
const ref = this.storage.ref(path);
uploadTask
.snapshotChanges()
.pipe(
tap(snap => {
progress(true, 1024, 1024);
}),
finalize(() => {
ref.getDownloadURL().subscribe(downloadURL => {
load(downloadURL);
return {
abort: () => {
abort();
}
};
});
})
)
.subscribe();
},
load: (source, load, error, progress, abort, headers) => {
fetch(source)
.then(function(e) {
load(e.url);
})
.catch(function() {});
return {
abort: e => {
console.log(e);
abort();
}
};
}
},
dropValidation: true,
instantUpload: true,
acceptedFileTypes: ["image/*", "text/plain", "application/pdf"],
allowFileSizeValidation: true,
maxFileSize: "2MB"
}
|
Defined in src/app/app.component.ts:25
|
FilePond Options object. |
import { Component, ViewChild } from "@angular/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { AngularFireStorage } from "@angular/fire/storage";
import { finalize, tap } from "rxjs/operators";
import Utils from "../utilities/utilities";
/**
* Class AppComponent is our main angular component to upload and preview "text files, PDFs, images" and preview
*/
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent {
/** files property to be our files array to be binded and displayed */
files: any[] = [];
/** activeId property to be used for the carousel as a current slide id */
activeId: string;
/** declare filePond as filepond instance */
@ViewChild("filePond") filePond: any;
/**
* FilePond Options object.
*/
pondOptions = {
labelIdle: "Drop file here",
allowMultiple: true,
allowFileRename: true,
fileRenameFunction: file => {
return file.name.replace(/[&\/\\#,+()$~%'":*?<>{}]/g, "");
},
server: {
process: (fieldName, file, metadata, load, error, progress, abort) => {
const path = `files/${new Date().getTime()}_${file.name}`;
file.id = Utils.uniqueId();
const uploadTask = this.storage.upload(path, file);
const ref = this.storage.ref(path);
uploadTask
.snapshotChanges()
.pipe(
tap(snap => {
progress(true, 1024, 1024);
}),
finalize(() => {
ref.getDownloadURL().subscribe(downloadURL => {
load(downloadURL);
return {
abort: () => {
abort();
}
};
});
})
)
.subscribe();
},
load: (source, load, error, progress, abort, headers) => {
fetch(source)
.then(function(e) {
load(e.url);
})
.catch(function() {});
return {
abort: e => {
console.log(e);
abort();
}
};
}
},
dropValidation: true,
instantUpload: true,
acceptedFileTypes: ["image/*", "text/plain", "application/pdf"],
allowFileSizeValidation: true,
maxFileSize: "2MB"
};
/** We just define NgbModal,AngularFireStorage in the constructor */
constructor(
private modalService: NgbModal,
private storage: AngularFireStorage
) { }
/**
* Add files "returnced from the serve" to filepond component.
*/
async pushPondFiles(files) {
const pondFiles = [];
for (let i = 0; i < files.length; i++) {
const filedate = await Utils.getFileDate(files[i]);
let id = Utils.uniqueId();
this.files[i] = {
src: filedate.url,
name: filedate.meta.name,
size: filedate.meta.size,
id,
contentType: filedate.meta.contentType.split("/")[0],
type: filedate.meta.name.split(".").pop()
};
this.createThumb(
filedate.meta.contentType,
filedate.meta.name,
filedate.url,
this.files[i]
);
pondFiles[i] = {
source: filedate.url,
options: {
type: "local",
file: {
id: id,
name: filedate.meta.name,
size: filedate.meta.size,
type: filedate.meta.name.split(".").pop()
}
}
};
this.filePond.pond.setOptions({ files: pondFiles });
}
}
/**
* Read data from filepond file instance and create object and push it to our files array.
*/
async pushFile(file) {
const obj: any = {
name: file.name,
size: file.size,
id: file.id,
contentType: file.type.split("/")[0],
type: file.name.split(".").pop()
};
obj.src = await Utils.generateUploadedFileUrl(file);
this.createThumb(file.type, file.name, obj.src, obj);
this.files.push(obj);
}
/**
* Add Thumb to the file "Thumb will be the same as photo source in case of images or generated from pdf first page or placeholder for txt files.
*/
async createThumb(contentType, name, url, obj) {
if (contentType.split("/")[0] === "image") {
obj.thumb = url;
} else if (name.split(".").pop() === "pdf") {
obj.thumb = await Utils.generatePDFThumb(obj.src);
} else {
obj.thumb = "https://firebasestorage.googleapis.com/v0/b/angular-file-upload-preview.appspot.com/o/text.png?alt=media&token=07736b8e-3c71-4557-a4fc-8067bbb47139";
}
}
/**
* Remove file from filepond and hence trigger pondHandleRemoveFile which will remove it from the thumbnails list.
*/
removeFile(id) {
const file = this.filePond.pond.getFiles().find(a => a.file.id === id);
this.filePond.pond.removeFile(file.id);
}
// Filepond functions
/**
* This Event fires after filepond initialized then we can add to it the files comes from the server.
*/
pondHandleInit() {
// console.log("FilePond has initialised", this.filePond);
// Simulate retreive 3 files from the server and display it.
this.pushPondFiles([
this.storage.ref("lorem.txt"),
this.storage.ref("pdf-test.pdf"),
this.storage.ref("planet.jpeg")
]);
}
/**
* This Event fires after file uploaded successfuly so we can push this file to our files array to be displayed.
*/
pondHandleProcessFile(event: any) {
this.pushFile(event.file.file);
}
/**
* This Event fires after file removedfrom filepond so we can delete this file from our files array to not be displayed.
*/
pondHandleRemoveFile(event: any) {
// console.log(event);
// this.removeFile(event.file.file.id);
this.files.splice(
this.files.findIndex(a => a.id === event.file.file.id),
1
);
}
// End of Filepond functions
// Modal and Carousel Functions
/**
* update the active slide ID from the modal.
*/
logSlide(ev: any) {
this.activeId = ev.current;
}
/**
* Open ngbootstrap modal with current slide activated and add specific class modal-reader to the modal.
*/
open(content: any, slide: string) {
this.activeId = slide;
this.modalService.open(content, { windowClass: "modal-reader" });
}
// Modal and Carousel Functions
}
<div class="attachment__control">
<file-pond
#filePond
[options]="pondOptions"
(oninit)="pondHandleInit()"
(onremovefile)="pondHandleRemoveFile($event)"
(onprocessfile)="pondHandleProcessFile($event)">
</file-pond>
<div class="text-center thumbs-container">
<div *ngFor="let file of files;let i = index" class="thumb__item img-thumbnail">
<img *ngIf="file.thumb" [src]="file.thumb" (click)="open(content, file.id)">
<div class="thumb__item--data">
<i [ngClass]="'fiv-cla fiv-icon-'+file.type"></i>
<span class="thumb__item--filename">{{file.name}}</span>
</div>
<div class="thumb-loader">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<button type="button" class="btn btn-sm btn-outline-dark thumb__item--remove" (click)="removeFile(file.id)"><span aria-hidden="true">×</span></button>
</div>
</div>
</div>
<ng-template #content let-d="dismiss">
<button type="button" class="close" aria-label="Close" (click)="d('')">
<span aria-hidden="true">×</span>
</button>
<ngb-carousel *ngIf="files" [(activeId)]="activeId" #fileCarousel="ngbCarousel" (slide)="logSlide($event)" interval="100000">
<ng-template ngbSlide *ngFor="let file of files;let i = index" [id]="file.id">
<h4 class="filename">{{file.name}}</h4>
<app-txtreader [src]="file.src" *ngIf="file.type === 'txt'"></app-txtreader>
<app-imgpreviewer [src]="file.src" *ngIf="file.contentType === 'image'"></app-imgpreviewer>
<ngx-extended-pdf-viewer [showOpenFileButton]="false" [src]="file.src" *ngIf="file.type == 'pdf' && activeId === file.id" useBrowserLocale="false"></ngx-extended-pdf-viewer>
</ng-template>
</ngb-carousel>
</ng-template>
./app.component.scss
.fiv-cla {
width: 2em;
line-height: 3em;
}
.attachment__control {
background: #f1f0ef;
border-radius: 0.5em;
.thumbs-container {
display: flex;
margin-top: -0.5em;
padding: 0.5em;
.thumb__item {
margin: 0.5em;
position: relative;
overflow: hidden;
min-width: 100px;
img {
height: 140px;
position: relative;
z-index: 2;
background: #fff;
}
&--data {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
font-size: 0.8em;
background: rgba(0, 0, 0, 0.4);
opacity: 0;
border-radius: 0.25rem;
transform: scale(0);
transition: opacity, transform 0.2s ease;
pointer-events: none;
}
&--remove {
position: absolute;
top: 5px;
right: 5px;
line-height: 1;
padding: 0.125rem 0.25rem;
font-size: 1rem;
z-index: 2;
&:not(:hover):not(:active) {
background: #fff;
}
}
&:hover {
.thumb__item--data {
opacity: 1;
transform: scale(1);
}
}
}
}
}
.thumb-loader {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform-origin: center center;
span {
display: inline-block;
width: 2px;
height: 20px;
margin: 40px 2px;
background-color: #3498db;
&:nth-child(1) {
animation: grow 1s ease-in-out infinite;
}
&:nth-child(2) {
animation: grow 1s ease-in-out 0.15s infinite;
}
&:nth-child(3) {
animation: grow 1s ease-in-out 0.3s infinite;
}
&:nth-child(4) {
animation: grow 1s ease-in-out 0.45s infinite;
}
}
}
@keyframes grow {
0%,
100% {
transform: scaleY(1);
}
50% {
transform: scaleY(1.8);
}
}