mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 13:02:56 +00:00
pull from developer-prod made
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DomSanitizerService } from './DomSanitizer.service';
|
||||
|
||||
describe('ActiveTabService', () => {
|
||||
let service: DomSanitizerService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(DomSanitizerService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Injectable, SecurityContext } from '@angular/core';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { Router } from '@angular/router';
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DomSanitizerService {
|
||||
|
||||
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
sanitizeInput(input: string) {
|
||||
// Encode special characters to prevent XSS attacks
|
||||
const encodedInput = this.encodeSpecialCharacters(input);
|
||||
|
||||
// Use DomSanitizer to sanitize the content
|
||||
return this.sanitizer.sanitize(SecurityContext.HTML, encodedInput);
|
||||
}
|
||||
|
||||
private encodeSpecialCharacters(input: string): string {
|
||||
// You can use a library like DOMPurify to encode special characters
|
||||
return DOMPurify.sanitize(input);
|
||||
|
||||
// If you don't want to use an external library, you can manually encode
|
||||
// Here's a simple example, you may need to extend this based on your requirements
|
||||
/* return input.replace(/</g, '<').replace(/>/g, '>'); */
|
||||
}
|
||||
|
||||
/* sanitizeInput(input: string): string {
|
||||
return this.sanitizer.sanitize(SecurityContext.HTML, input);
|
||||
} */
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
export type Either<T, E> = { isOk: true; isError: false, value: T } | { isOk: false; isError: true, error: E };
|
||||
|
||||
export function ok<T, E>(value: T): Either<T, E> {
|
||||
return { isOk: true, isError: false, value };
|
||||
}
|
||||
|
||||
export function error<T, E>(error: E): Either<T, E> {
|
||||
return { isOk: false, isError: true, error};
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CustomCalendarEvent, EventListStore } from 'src/app/models/agenda/AgendaEventList';
|
||||
import { DateService } from '../date.service';
|
||||
import { momentG } from 'src/plugin/momentG';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -8,12 +9,13 @@ import { DateService } from '../date.service';
|
||||
export class ListBoxService {
|
||||
|
||||
height = "unset"
|
||||
|
||||
|
||||
|
||||
constructor(
|
||||
private dateService: DateService
|
||||
){}
|
||||
|
||||
|
||||
|
||||
filterProfile(eventSource: EventListStore[] = [], profile: 'md' | 'pr' | 'all') {
|
||||
return eventSource.filter((e) => e.profile == profile)
|
||||
}
|
||||
@@ -21,7 +23,7 @@ export class ListBoxService {
|
||||
getEventInsideRange(eventSource: EventListStore[], rangeStartDate, randEndDate) {
|
||||
return eventSource.filter((e)=> {
|
||||
if(new Date(rangeStartDate).getTime() <= new Date(e.startTime).getTime() &&
|
||||
new Date(randEndDate).getTime() >= new Date(e.endTime).getTime()) {
|
||||
new Date(randEndDate).getTime() >= new Date(e.endTime).getTime()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -29,43 +31,84 @@ export class ListBoxService {
|
||||
}
|
||||
|
||||
filterSegment(eventSource: EventListStore[], segment): EventListStore[] {
|
||||
|
||||
|
||||
return eventSource.filter( data => data.calendarName == segment)
|
||||
}
|
||||
|
||||
daysBetween(){ }
|
||||
|
||||
list(eventSource: EventListStore[], profile: 'md' | 'pr' | 'all', rangeStartDate, randEndDate, {segment = 'Combinado', selectedDate= null}) {
|
||||
list(eventSource: EventListStore[], profile: 'md' | 'pr' | 'all', rangeStartDate, randEndDate, {segment = 'Combinado', selectedDate= null}): Year[] {
|
||||
|
||||
// // filter range
|
||||
// if(selectedDate) {
|
||||
// eventSource = eventSource.filter(data =>
|
||||
// data.startTime.toLocaleDateString('pt') >= new Date(rangeStartDate).toLocaleDateString('pt') &&
|
||||
// eventSource = eventSource.filter(data =>
|
||||
// data.startTime.toLocaleDateString('pt') >= new Date(rangeStartDate).toLocaleDateString('pt') &&
|
||||
// data.startTime.toLocaleDateString('pt') <= new Date(rangeStartDate).toLocaleDateString('pt')
|
||||
// )
|
||||
// }
|
||||
|
||||
|
||||
if(segment!='Combinado') {
|
||||
eventSource = this.filterSegment(eventSource, segment)
|
||||
eventSource = this.filterSegment(eventSource, segment)
|
||||
}
|
||||
|
||||
|
||||
// if(profile != 'all') {
|
||||
// eventSource = this.filterProfile(eventSource, profile)
|
||||
// }
|
||||
|
||||
let newStracture:CustomCalendarEvent[];
|
||||
|
||||
let newStracture:CustomCalendarEvent[];
|
||||
newStracture = this.encapsulation(eventSource);
|
||||
|
||||
return this.display(newStracture, selectedDate)
|
||||
// const object = {}
|
||||
|
||||
// for (const e of newStracture.reverse()) {
|
||||
// if(!object[momentG(new Date(e.start), 'MMMM yyyy')]) {
|
||||
// object[momentG(new Date(e.start), 'MMMM yyyy')] = []
|
||||
// }
|
||||
// object[momentG(new Date(e.start), 'MMMM yyyy')].push(e)
|
||||
// }
|
||||
|
||||
// console.log({object})
|
||||
|
||||
// const daysStringNum = Object.keys(object).reverse()
|
||||
|
||||
// const daysObject = {}
|
||||
|
||||
// for(const day of daysStringNum) {
|
||||
// daysObject[day] = object[day]
|
||||
// }
|
||||
|
||||
// console.log({daysObject})
|
||||
|
||||
|
||||
return this.display(newStracture, selectedDate).year
|
||||
|
||||
// console.log({daysObject})
|
||||
|
||||
// const daysStringNum = Object.keys(daysObject)
|
||||
|
||||
// for(const day of daysStringNum) {
|
||||
// daysObject[day] = daysObject[day].reverse()
|
||||
// }
|
||||
|
||||
|
||||
// daysObject = this.transformObjectKeyOrder(daysObject, daysStringNum)
|
||||
|
||||
// return daysObject
|
||||
}
|
||||
|
||||
sortArrayISODate(myArray: any): any[] {
|
||||
|
||||
return myArray.sort((a,b) =>
|
||||
Date.parse(b.start )
|
||||
-
|
||||
Date.parse(a.start))
|
||||
}
|
||||
|
||||
display(list: CustomCalendarEvent[], selectedDate) {
|
||||
let days = {};
|
||||
const year: Year[] = []
|
||||
|
||||
list.forEach( (event:CustomCalendarEvent, index) => {
|
||||
|
||||
this.sortArrayISODate(list).reverse().forEach( (event:CustomCalendarEvent, index) => {
|
||||
|
||||
var startDate: any = new Date(event.start);
|
||||
|
||||
@@ -74,8 +117,8 @@ export class ListBoxService {
|
||||
endTime: event.end
|
||||
})
|
||||
|
||||
const day = this.dateService.getDay(event.start)
|
||||
|
||||
const day = this.dateService.getDay(event.start)
|
||||
|
||||
event['manyDays'] = !this.dateService.isSameDate(event.start, event.end)
|
||||
event['todayOnly'] = this.dateService.isSameDate(event.start, event.end)
|
||||
|
||||
@@ -94,56 +137,58 @@ export class ListBoxService {
|
||||
if (diffDays >= 1) {
|
||||
|
||||
const StartEvent = this.transForm(event, {startMany: true, endMany: false, middle: false})
|
||||
|
||||
if(this.CanPush(event, selectedDate)) days[day].push(StartEvent)
|
||||
|
||||
|
||||
if(this.CanPush(event, selectedDate)) {days[day].push(StartEvent); this.push(StartEvent, year)}
|
||||
|
||||
let i = 1;
|
||||
|
||||
|
||||
// create event between date
|
||||
while (startDate.getFullYear() != endDate.getFullYear() ||
|
||||
while (startDate.getFullYear() != endDate.getFullYear() ||
|
||||
startDate.getMonth() != endDate.getMonth() ||
|
||||
startDate.getDate() != endDate.getDate()) {
|
||||
|
||||
const newDate = startDate.setDate(startDate.getDate()+ i)
|
||||
let otherDays = this.dateService.getDay(newDate)
|
||||
|
||||
let otherDays = this.dateService.getDay(newDate)
|
||||
|
||||
event['other'] = true
|
||||
|
||||
|
||||
event.start = newDate
|
||||
if(!days.hasOwnProperty(otherDays)) {
|
||||
|
||||
days[otherDays] = []
|
||||
}
|
||||
|
||||
if (!(startDate.getFullYear() != endDate.getFullYear() ||
|
||||
|
||||
if (!(startDate.getFullYear() != endDate.getFullYear() ||
|
||||
startDate.getMonth() != endDate.getMonth() ||
|
||||
startDate.getDate() != endDate.getDate())) {
|
||||
// last push
|
||||
|
||||
const EndEvent = this.transForm(event, {startMany: false, endMany: true, middle: false})
|
||||
if(this.CanPush(event, selectedDate)) days[otherDays].push(EndEvent)
|
||||
if(this.CanPush(event, selectedDate)) {days[otherDays].push(EndEvent) ; this.push(event, year)}
|
||||
|
||||
} else {
|
||||
|
||||
const EndEvent = this.transForm(event, {startMany: false,endMany: true, middle: true})
|
||||
if(this.CanPush(event, selectedDate)) days[otherDays].push(EndEvent)
|
||||
if(this.CanPush(event, selectedDate)) {days[otherDays].push(EndEvent) ; this.push(event, year)}
|
||||
}
|
||||
|
||||
|
||||
days[otherDays] = days[otherDays].reverse()
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if(this.CanPush(event, selectedDate)) days[day].push(event)
|
||||
if(this.CanPush(event, selectedDate)) { days[day].push(event) ; this.push(event, year) }
|
||||
}
|
||||
} else {
|
||||
if(this.CanPush(event, selectedDate)) days[day].push(event)
|
||||
if(this.CanPush(event, selectedDate)) { days[day].push(event) ; this.push(event, year) }
|
||||
}
|
||||
} else {
|
||||
if(this.CanPush(event, selectedDate) && diffDays != 2) days[day].push(event)
|
||||
if(this.CanPush(event, selectedDate) && diffDays != 2) { days[day].push(event) ; this.push(event, year) }
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
})
|
||||
|
||||
@@ -157,14 +202,73 @@ export class ListBoxService {
|
||||
|
||||
})
|
||||
|
||||
return days
|
||||
return {days, year}
|
||||
}
|
||||
|
||||
|
||||
push(event: any, year: Year[]) {
|
||||
const date = new Date(event.start)
|
||||
|
||||
const yearName = momentG(new Date(date), 'yyyy')
|
||||
const monthName = momentG(new Date(date), 'MMMM')
|
||||
const dayName = momentG(new Date(date), 'dd')
|
||||
|
||||
|
||||
let YearIndex = year.findIndex( x => x.yearInfo.yearName == yearName)
|
||||
|
||||
|
||||
|
||||
if(YearIndex == -1) {
|
||||
YearIndex = year.push({
|
||||
yearInfo: {
|
||||
yearName: yearName
|
||||
},
|
||||
months: []
|
||||
})
|
||||
|
||||
YearIndex--
|
||||
}
|
||||
|
||||
let MonthNameIndex = year[YearIndex].months.findIndex( x => x.monthInfo.monthName == monthName)
|
||||
|
||||
if(MonthNameIndex == -1) {
|
||||
MonthNameIndex = year[YearIndex].months.push({
|
||||
monthInfo: {
|
||||
monthName: monthName
|
||||
},
|
||||
days: []
|
||||
})
|
||||
|
||||
MonthNameIndex --
|
||||
}
|
||||
|
||||
let DayNameIndex = year[YearIndex].months[MonthNameIndex].days.findIndex( x => x.daysInfo.dayName == dayName)
|
||||
|
||||
if(DayNameIndex == -1) {
|
||||
year[YearIndex].months[MonthNameIndex].days.push({
|
||||
daysInfo: {
|
||||
dayName: dayName
|
||||
},
|
||||
events: [event]
|
||||
})
|
||||
} else {
|
||||
year[YearIndex].months[MonthNameIndex].days[DayNameIndex].events.push(event)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CanPush(event: any, selectedDate: Date) {
|
||||
|
||||
return new Date(event.start).getMonth() == selectedDate.getMonth() &&
|
||||
new Date(event.start).getFullYear() == selectedDate.getFullYear() &&
|
||||
new Date(event.start).getDate() >= selectedDate.getDate()
|
||||
const limite = this.endOfMonth(selectedDate)
|
||||
limite.setDate(limite.getDate() + 10)
|
||||
limite.setHours(0)
|
||||
|
||||
selectedDate.setHours(0);
|
||||
selectedDate.setMinutes(0);
|
||||
selectedDate.setSeconds(0);
|
||||
|
||||
return (selectedDate.getTime() <= new Date(event.start).getTime() || selectedDate.getTime() <= new Date(event.end).getTime()) &&
|
||||
(limite.getTime() >= new Date(event.start).getTime() || limite.getTime() >= new Date(event.end).getTime())
|
||||
}
|
||||
|
||||
encapsulation(eventsList:EventListStore[]): CustomCalendarEvent[] {
|
||||
@@ -173,7 +277,7 @@ export class ListBoxService {
|
||||
let events: CustomCalendarEvent[] = [];
|
||||
|
||||
eventsList.forEach((element, eventIndex) => {
|
||||
|
||||
|
||||
events.push({
|
||||
start: new Date(element.startTime),
|
||||
end: new Date(element.endTime),
|
||||
@@ -209,4 +313,97 @@ export class ListBoxService {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
transformObjectKeyOrder(originalObject, keyOrder) {
|
||||
const transformedObject = {};
|
||||
|
||||
for (const key of keyOrder) {
|
||||
if (originalObject.hasOwnProperty(key)) {
|
||||
transformedObject[key] = originalObject[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Include any remaining keys not in the specified order
|
||||
for (const key in originalObject) {
|
||||
if (!keyOrder.includes(key) && originalObject.hasOwnProperty(key)) {
|
||||
transformedObject[key] = originalObject[key];
|
||||
}
|
||||
}
|
||||
|
||||
return transformedObject;
|
||||
}
|
||||
|
||||
|
||||
endOfMonth(myDate){
|
||||
let date = new Date(myDate);
|
||||
date.setDate(1); // Avoids edge cases on the 31st day of some months
|
||||
date.setMonth(date.getMonth() +1);
|
||||
date.setDate(0);
|
||||
date.setHours(23);
|
||||
date.setMinutes(59);
|
||||
date.setSeconds(59);
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
interface DayInfo {
|
||||
// Define properties for dayInfo here
|
||||
dayName: string
|
||||
}
|
||||
|
||||
interface Day {
|
||||
// Define properties for day here
|
||||
|
||||
}
|
||||
|
||||
interface Month {
|
||||
monthInfo: {
|
||||
monthName: string
|
||||
// Define properties for yearInfo inside months here
|
||||
}
|
||||
days: {
|
||||
daysInfo: DayInfo;
|
||||
events: Day[];
|
||||
}[]
|
||||
}
|
||||
|
||||
interface Year {
|
||||
yearInfo: {
|
||||
yearName: string
|
||||
// Define properties for yearInfo here
|
||||
};
|
||||
months: Month[];
|
||||
}
|
||||
|
||||
const years: Year[] = [
|
||||
{
|
||||
yearInfo: {
|
||||
yearName: ""
|
||||
// Define properties for yearInfo inside the first year here
|
||||
},
|
||||
months: [
|
||||
{
|
||||
monthInfo: {
|
||||
monthName: "",
|
||||
// Define properties for yearInfo inside the first month here
|
||||
},
|
||||
days: [
|
||||
{
|
||||
daysInfo: {
|
||||
dayName: "",
|
||||
// Define properties for dayInfo inside the first day here
|
||||
},
|
||||
events: [
|
||||
{
|
||||
// Define properties for the first day here
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
// Add more months here as needed
|
||||
],
|
||||
},
|
||||
// Add more years here as needed
|
||||
];
|
||||
|
||||
@@ -319,6 +319,8 @@ export class MessageService {
|
||||
if(params?.attachments) {
|
||||
if(params?.attachments[0]?.image_url) {
|
||||
delete params?.attachments[0]?.image_url
|
||||
delete params?.file?.image_url
|
||||
// delete
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { InputFilterDirective } from './input-filter.directive';
|
||||
|
||||
describe('InputFilterDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new InputFilterDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Directive, ElementRef, HostListener, Input, SecurityContext } from '@angular/core';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
|
||||
@Directive({
|
||||
selector: '[appInputFilter]'
|
||||
})
|
||||
export class InputFilterDirective {
|
||||
|
||||
@Input() isAlphaNumeric: boolean;
|
||||
|
||||
constructor(private el: ElementRef, private sanitizer: DomSanitizer) {}
|
||||
|
||||
removeTags(inputValue) {
|
||||
const div = document.createElement("div");
|
||||
div.innerHTML = inputValue;
|
||||
var text = div.textContent || div.innerText || "";
|
||||
|
||||
return text
|
||||
}
|
||||
filter(inputValue) {
|
||||
|
||||
this.el.nativeElement.value = this.removeTags(inputValue)
|
||||
}
|
||||
|
||||
@HostListener('keypress', ['$event']) onInput(event: any): void {
|
||||
const inputValue: string = event.target.value;
|
||||
// Notify the subject when the input changes
|
||||
this.filter(inputValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,22 +21,22 @@ export class AttendeesPageModal implements OnInit {
|
||||
eventPersons: EventPerson[];
|
||||
adding: "intervenient" | "CC";
|
||||
currentPath = window.location.pathname;
|
||||
|
||||
|
||||
taskParticipants:EventPerson[] = [];
|
||||
taskParticipantsCc:EventPerson[] = [];
|
||||
loggeduser: LoginUserRespose;
|
||||
@Input() loggedAttendSon: boolean;
|
||||
taskType: any;
|
||||
|
||||
|
||||
|
||||
constructor(
|
||||
private modalCtrl: ModalController,
|
||||
private modalCtrl: ModalController,
|
||||
private contactsService: ContactsService,
|
||||
private navParams: NavParams,
|
||||
private modalController: ModalController,
|
||||
public ThemeService: ThemeService,
|
||||
private router: Router,) {
|
||||
|
||||
|
||||
this.adding = this.navParams.get('adding');
|
||||
this.taskParticipants = this.navParams.get('taskParticipants');
|
||||
this.taskParticipantsCc = this.navParams.get('taskParticipantsCc');
|
||||
@@ -48,7 +48,7 @@ export class AttendeesPageModal implements OnInit {
|
||||
ngOnInit() {
|
||||
console.log('Pesquisa de contactos current path2',this.router.url)
|
||||
this.fetchContacts("");
|
||||
|
||||
|
||||
if(this.taskParticipants == null || this.taskParticipants == undefined){
|
||||
this.taskParticipants = [];
|
||||
}
|
||||
@@ -56,9 +56,9 @@ export class AttendeesPageModal implements OnInit {
|
||||
if(this.taskParticipantsCc == null || this.taskParticipantsCc == undefined){
|
||||
this.taskParticipantsCc = [];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ngOnChanges(event) {}
|
||||
|
||||
save(){
|
||||
@@ -80,16 +80,16 @@ export class AttendeesPageModal implements OnInit {
|
||||
filterSearchList(itm: EventPerson): boolean {
|
||||
|
||||
const result = this.taskParticipants.concat( this.taskParticipantsCc).find((contact, index)=>{
|
||||
|
||||
|
||||
if(contact.Name.toLocaleLowerCase() == itm.Name.toLocaleLowerCase() && contact.EmailAddress.toLocaleLowerCase() == itm.EmailAddress.toLocaleLowerCase()){
|
||||
index = index;
|
||||
return contact;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
return undefined == result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
remove(itm: EventPerson){
|
||||
@@ -102,7 +102,7 @@ export class AttendeesPageModal implements OnInit {
|
||||
return contact;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
});
|
||||
|
||||
} else if (this.adding == "CC") {
|
||||
@@ -113,7 +113,7 @@ export class AttendeesPageModal implements OnInit {
|
||||
return contact;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export class AttendeesPageModal implements OnInit {
|
||||
if(this.adding == "intervenient"){
|
||||
itm.IsRequired = true;
|
||||
this.taskParticipants.push(itm);
|
||||
|
||||
|
||||
} else if (this.adding == "CC") {
|
||||
itm.IsRequired = false;
|
||||
this.taskParticipantsCc.push(itm);
|
||||
@@ -141,7 +141,7 @@ export class AttendeesPageModal implements OnInit {
|
||||
const index: number = result.findIndex((cont) => {
|
||||
return cont.EmailAddress.toLocaleLowerCase() == attendee.EmailAddress.toLocaleLowerCase()
|
||||
});
|
||||
|
||||
|
||||
result.splice(index, 1);
|
||||
});
|
||||
}
|
||||
@@ -151,12 +151,12 @@ export class AttendeesPageModal implements OnInit {
|
||||
this.showLoader = false;
|
||||
} else {
|
||||
this.contacts = result;
|
||||
console.log('Attendes Email',this.loggeduser.Email)
|
||||
// console.log('Attendes Email',this.loggeduser.Email)
|
||||
let filterLoggedUserEmail = this.contacts.filter(item => item.EmailAddress.toLocaleLowerCase() != this.loggeduser.Email.toLocaleLowerCase())
|
||||
console.log('Attendes Email', filterLoggedUserEmail)
|
||||
// console.log('Attendes Email', filterLoggedUserEmail)
|
||||
let filterEmptyEmail = filterLoggedUserEmail.filter(item => item.EmailAddress.toLocaleLowerCase() != "")
|
||||
this.contacts = filterEmptyEmail;
|
||||
console.log('Attendes Email', this.contacts)
|
||||
// console.log('Attendes Email', this.contacts)
|
||||
this.showLoader = false;
|
||||
|
||||
}
|
||||
@@ -164,4 +164,4 @@ export class AttendeesPageModal implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class FileLoaderService {
|
||||
// input.onchange = () => {
|
||||
// // you can use this method to get file and perform respective operations
|
||||
// let files = Array.from(input.files);
|
||||
//
|
||||
//
|
||||
// };
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FileValidatorService } from './file-validator.service';
|
||||
|
||||
describe('FileValidatorService', () => {
|
||||
let service: FileValidatorService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(FileValidatorService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,173 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Either, error, ok} from "src/app/services/Either"
|
||||
import * as Sentry from '@sentry/capacitor';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FileValidatorService {
|
||||
|
||||
forbiddenExtensions = [
|
||||
".exe",
|
||||
".bat",
|
||||
".sh",
|
||||
".jar",
|
||||
".js",
|
||||
".vbs",
|
||||
".ps1",
|
||||
".ini",
|
||||
".config",
|
||||
".zip",
|
||||
".rar",
|
||||
".tar.gz",
|
||||
".7z",
|
||||
".cab",
|
||||
".sql",
|
||||
".bak",
|
||||
".htaccess",
|
||||
".htpasswd",
|
||||
".scr",
|
||||
".pif",
|
||||
".com",
|
||||
".msi",
|
||||
".dll",
|
||||
".sys",
|
||||
".ini",
|
||||
".docm",
|
||||
".xlsm",
|
||||
".pptm",
|
||||
".rtf",
|
||||
".so",
|
||||
".dylib",
|
||||
".dat",
|
||||
".log",
|
||||
".conf",
|
||||
".php",
|
||||
".py",
|
||||
".rb",
|
||||
];
|
||||
|
||||
constructor() { }
|
||||
|
||||
private base64ToBlob(base64) {
|
||||
const binaryData = atob(base64);
|
||||
const arrayBuffer = new ArrayBuffer(binaryData.length);
|
||||
const view = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < binaryData.length; i++) {
|
||||
view[i] = binaryData.charCodeAt(i);
|
||||
}
|
||||
return new Blob([arrayBuffer], { type: 'video/mp4' }); // Adjust the type as per your video format
|
||||
}
|
||||
|
||||
ValidateImage(base64Image: string): Promise<Either<true, Event>> {
|
||||
const imageDiv: HTMLImageElement = document.createElement("img")
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
imageDiv.onload = () => {
|
||||
resolve(ok(true))
|
||||
}
|
||||
|
||||
imageDiv.onerror = (e: Event) => {
|
||||
resolve(error(e))
|
||||
Sentry.captureMessage('FileValidatorService invalid image content');
|
||||
}
|
||||
|
||||
imageDiv.src = base64Image
|
||||
})
|
||||
}
|
||||
|
||||
ValidateVideoFromBase64Data(base64Data: string) : Promise<Either<true, false>> {
|
||||
const blob = this.base64ToBlob(base64Data);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const videoElement = document.createElement('video');
|
||||
videoElement.src = URL.createObjectURL(blob);
|
||||
|
||||
// Add event listeners to handle video load and error
|
||||
videoElement.addEventListener('loadeddata', () => {
|
||||
resolve(ok(true))
|
||||
// You can also perform additional validation checks here if needed.
|
||||
});
|
||||
|
||||
videoElement.addEventListener('error', () => {
|
||||
resolve(ok(true))
|
||||
Sentry.captureMessage('FileValidatorService invalid video content');
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
ValidateVideoFromBlob(blob: Blob) : Promise<Either<true, false>> {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const videoElement = document.createElement('video');
|
||||
videoElement.src = URL.createObjectURL(blob);
|
||||
|
||||
// Add event listeners to handle video load and error
|
||||
videoElement.addEventListener('loadeddata', () => {
|
||||
resolve(ok(true))
|
||||
// You can also perform additional validation checks here if needed.
|
||||
});
|
||||
|
||||
videoElement.addEventListener('error', () => {
|
||||
resolve(ok(true))
|
||||
Sentry.captureMessage('FileValidatorService invalid video content');
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
validateAudioFromBlob(blob: Blob): Promise<Either<true, false>> {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const audioElement = new Audio();
|
||||
|
||||
|
||||
// Add event listeners to handle audio load and error
|
||||
audioElement.addEventListener('canplaythrough', () => {
|
||||
console.log('Valid audio');
|
||||
resolve(ok(true))
|
||||
// You can also perform additional validation checks here if needed.
|
||||
});
|
||||
|
||||
audioElement.addEventListener('error', () => {
|
||||
console.log('Invalid audio');
|
||||
resolve(error(false))
|
||||
});
|
||||
|
||||
|
||||
audioElement.src = URL.createObjectURL(blob);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
hasDuplicateExtension(filename): Either<true, false> {
|
||||
// Use a regular expression to match multiple consecutive dots
|
||||
const duplicateExtensionRegex = /\.\.+/;
|
||||
const a = duplicateExtensionRegex.test(filename);
|
||||
if(a) {
|
||||
return ok(true)
|
||||
} else {
|
||||
Sentry.captureMessage('FileValidatorService invalid filename '+ filename);
|
||||
return error(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileNameValidation(fileName): Either<true, false> {
|
||||
const fileExtension = fileName.slice(((fileName.lastIndexOf(".") - 1) >>> 0) + 2);
|
||||
|
||||
const found = this.forbiddenExtensions.includes(`.${fileExtension.toLowerCase()}`);
|
||||
|
||||
if(found) {
|
||||
return error(false)
|
||||
} else {
|
||||
return ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -91,7 +91,7 @@ export class HttpErrorHandle {
|
||||
validationMessagge(service: string, callback?: any) {
|
||||
switch (service) {
|
||||
case 'diplomaAsDraft':
|
||||
this.toastService._badRequest('Este diploma não contem um draft para ser assinado!')
|
||||
this.toastService._badRequest('Este diploma não contem um rascunho para ser assinado!')
|
||||
break;
|
||||
case 'filetype':
|
||||
this.toastService._badRequest('Formato de ficheiro inválido!')
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HttpServiceService } from './http-service.service';
|
||||
|
||||
describe('HttpServiceService', () => {
|
||||
let service: HttpServiceService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(HttpServiceService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { HttpClient, HttpContext, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
// import { Result, err, ok } from 'neverthrow'
|
||||
import { tap, shareReplay, catchError } from "rxjs/operators";
|
||||
import { Observable, of } from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class HttpServiceService {
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
|
||||
put(url: string, body: any | null, options: Options): Observable<any> {
|
||||
return this.http.put(url, body, options as any).pipe(
|
||||
tap((response) => {
|
||||
// Handle success response if needed
|
||||
}),
|
||||
catchError((error) => {
|
||||
// Handle error response if needed
|
||||
return of(error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface Options {
|
||||
headers?: HttpHeaders | {
|
||||
[header: string]: string | string[];
|
||||
};
|
||||
context?: HttpContext;
|
||||
observe?: 'body';
|
||||
params?: HttpParams | {
|
||||
[param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
|
||||
};
|
||||
reportProgress?: boolean;
|
||||
responseType?: 'arraybuffer';
|
||||
withCredentials?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TokenInterceptorService } from './token-interceptor.service';
|
||||
|
||||
describe('TokenInterceptorService', () => {
|
||||
let service: TokenInterceptorService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(TokenInterceptorService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,81 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import {
|
||||
HttpRequest,
|
||||
HttpHandler,
|
||||
HttpEvent,
|
||||
HttpInterceptor,
|
||||
HttpErrorResponse,
|
||||
HTTP_INTERCEPTORS,
|
||||
} from "@angular/common/http";
|
||||
import { Observable, throwError, BehaviorSubject } from "rxjs";
|
||||
import { catchError, filter, take, switchMap } from "rxjs/operators";
|
||||
import { SessionStore } from "src/app/store/session.service";
|
||||
import { MiddlewareRepositoryService } from "src/app/repository/middleWare/middleware-repository.service"
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TokenInterceptorService {
|
||||
|
||||
private isRefreshing = false;
|
||||
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(
|
||||
null
|
||||
);
|
||||
|
||||
|
||||
constructor(private middlewareRepositoryService: MiddlewareRepositoryService) {
|
||||
this.middlewareRepositoryService = middlewareRepositoryService
|
||||
}
|
||||
|
||||
intercept(
|
||||
request: HttpRequest<any>,
|
||||
next: HttpHandler
|
||||
): Observable<HttpEvent<any>> {
|
||||
if (SessionStore.user.Authorization) {
|
||||
request = this.addToken(request, SessionStore.user.Authorization);
|
||||
}
|
||||
|
||||
return next.handle(request).pipe(
|
||||
catchError((error) => {
|
||||
if (error instanceof HttpErrorResponse && error.status === 401) {
|
||||
return this.handle401Error(request, next);
|
||||
} else {
|
||||
return throwError(error);
|
||||
}
|
||||
})
|
||||
) as any
|
||||
}
|
||||
|
||||
private addToken(request: HttpRequest<any>, token: string) {
|
||||
return request.clone({
|
||||
setHeaders: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
|
||||
if (!this.isRefreshing) {
|
||||
this.isRefreshing = true;
|
||||
this.refreshTokenSubject.next(null);
|
||||
|
||||
|
||||
|
||||
return this.middlewareRepositoryService.refreshToken().pipe(
|
||||
switchMap((token: any) => {
|
||||
this.isRefreshing = false;
|
||||
this.refreshTokenSubject.next(token['result'].accessToken);
|
||||
return next.handle(this.addToken(request, token['result'].accessToken));
|
||||
})
|
||||
);
|
||||
} else {
|
||||
return this.refreshTokenSubject.pipe(
|
||||
filter((token) => token != null),
|
||||
take(1),
|
||||
switchMap((jwt) => {
|
||||
return next.handle(this.addToken(request, jwt));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,17 +239,22 @@ export class NotificationsService {
|
||||
}
|
||||
);
|
||||
} else {
|
||||
navigator.serviceWorker.onmessage = (event) => {
|
||||
console.log('Mensagem recebida do Service Worker:', event.data.data);
|
||||
let object = {
|
||||
notification: event.data
|
||||
}
|
||||
try {
|
||||
|
||||
if (event.data.notificationClicked) {
|
||||
console.log('Notificação push do Firebase clicada em segundo plano!');
|
||||
this.notificatinsRoutes(object)
|
||||
}
|
||||
};
|
||||
navigator.serviceWorker.onmessage = (event) => {
|
||||
console.log('Mensagem recebida do Service Worker:', event.data.data);
|
||||
let object = {
|
||||
notification: event.data
|
||||
}
|
||||
|
||||
if (event.data.notificationClicked) {
|
||||
console.log('Notificação push do Firebase clicada em segundo plano!');
|
||||
this.notificatinsRoutes(object)
|
||||
}
|
||||
};
|
||||
} catch(e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChunkService } from './chunk.service';
|
||||
|
||||
describe('ChunkService', () => {
|
||||
let service: ChunkService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ChunkService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ChunkService {
|
||||
|
||||
constructor() {
|
||||
window["ChunkService"] = this
|
||||
|
||||
// const a = this.generateChunkFile({} as any, {} as any)
|
||||
}
|
||||
|
||||
generateChunkFile(base64: string, chunkSizeInBytes: number): File[] {
|
||||
const byteCharacters = atob(base64); // Decode base64 data to binary
|
||||
const chunks: File[] = [];
|
||||
let start = 0;
|
||||
|
||||
function createChunk(): File {
|
||||
const chunkSize = Math.min(chunkSizeInBytes, byteCharacters.length - start);
|
||||
const chunkData = byteCharacters.slice(start, start + chunkSize);
|
||||
start += chunkSize;
|
||||
|
||||
// console.log({chunkData})
|
||||
|
||||
const chunkArray = new Uint8Array(chunkData.length);
|
||||
|
||||
|
||||
for (let i = 0; i < chunkData.length; i++) {
|
||||
chunkArray[i] = chunkData.charCodeAt(i);
|
||||
// console.log('chunkData.charCodeAt', chunkData.charCodeAt(i))
|
||||
}
|
||||
|
||||
// console.log({Uint8Array:"Uint8Array", chunkArray})
|
||||
|
||||
const blob = new Blob([chunkArray]);
|
||||
// console.log('blob')
|
||||
// console.log('File')
|
||||
return new File([blob], `chunk_${chunks.length + 1}`);
|
||||
}
|
||||
|
||||
while (start < byteCharacters.length) {
|
||||
chunks.push(createChunk());
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
generateChunkOfUint8Array(base64: string, chunkSizeInBytes: number): Uint8Array[] {
|
||||
const byteCharacters = atob(base64); // Decode base64 data to binary
|
||||
const chunks: Uint8Array[] = [];
|
||||
let start = 0;
|
||||
|
||||
function createChunk(): Uint8Array {
|
||||
const chunkSize = Math.min(chunkSizeInBytes, byteCharacters.length - start);
|
||||
const chunkData = byteCharacters.slice(start, start + chunkSize);
|
||||
start += chunkSize;
|
||||
|
||||
const chunkArray = new Uint8Array(chunkData.length);
|
||||
|
||||
|
||||
for (let i = 0; i < chunkData.length; i++) {
|
||||
chunkArray[i] = chunkData.charCodeAt(i);
|
||||
}
|
||||
|
||||
return chunkArray;
|
||||
}
|
||||
|
||||
while (start < byteCharacters.length) {
|
||||
chunks.push(createChunk());
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
async uploadChunk(file: File): Promise<any> {
|
||||
// Read and upload the file in chunks (as you've previously implemented)
|
||||
const chunkSize = 1024 * 500; // Adjust the chunk size as needed
|
||||
const chunks = [];
|
||||
let offset = 0;
|
||||
|
||||
let i = 0
|
||||
|
||||
while (offset < file.size) {
|
||||
console.log(offset)
|
||||
const chunk = file.slice(offset, offset + chunkSize);
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
chunks[i] = new Uint8Array(reader.result as ArrayBuffer)
|
||||
};
|
||||
reader.readAsArrayBuffer(chunk);
|
||||
offset += chunkSize;
|
||||
}
|
||||
|
||||
return chunks
|
||||
}
|
||||
|
||||
onFileSelect(event: any, chunkSizeInBytes):Promise<Blob[]> {
|
||||
const file:File = event.target.files[0];
|
||||
const filename = file.name;
|
||||
//const chunkSize = 1024 * 1024; // 1 MB chunks (adjust as needed)
|
||||
const chunkSize = chunkSizeInBytes
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// Read and upload chunks
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = (e) => {
|
||||
const arrayBuffer = e.target.result as ArrayBuffer;
|
||||
const blob = new Blob([new Uint8Array(arrayBuffer)]);
|
||||
const totalChunks = Math.ceil(file.size / chunkSize);
|
||||
const chunks: Blob[] = []
|
||||
|
||||
for (let i = 1; i <= totalChunks; i++) {
|
||||
const start = (i - 1) * chunkSize;
|
||||
const end = i * chunkSize;
|
||||
const chunk = blob.slice(start, end);
|
||||
chunks.push(chunk)
|
||||
}
|
||||
|
||||
resolve(chunks)
|
||||
};
|
||||
|
||||
fileReader.readAsArrayBuffer(file);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
generateChunkFromBase64(base64: string, chunkSizeInBytes: number) {
|
||||
const byteCharacters = atob(base64); // Decode base64 data to binary
|
||||
const chunkArray = [];
|
||||
|
||||
for (let offset = 0; offset < byteCharacters.length; offset += chunkSizeInBytes) {
|
||||
const chunkData = byteCharacters.slice(offset, offset + chunkSizeInBytes);
|
||||
chunkArray.push(chunkData);
|
||||
}
|
||||
|
||||
return chunkArray;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StreamService } from './stream.service';
|
||||
|
||||
describe('StreamService', () => {
|
||||
let service: StreamService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(StreamService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,112 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class StreamService {
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
) {
|
||||
window["StreamService"] = this
|
||||
}
|
||||
|
||||
|
||||
async uploadFile() {
|
||||
const API_URL = 'http://localhost:3000/upload'; // Replace with your server URL
|
||||
const filePath = 'path/to/large-file.zip'; // Replace with the path to your file
|
||||
const fileName = 'my-file'; // Specify your desired filename
|
||||
const fileExtension = 'zip'; // Specify the file extension
|
||||
|
||||
const headers = new HttpHeaders()
|
||||
.append('X-File-Name', fileName)
|
||||
.append('X-File-Extension', fileExtension);
|
||||
|
||||
const file = await this.readFileInChunks(filePath);
|
||||
const chunkSize = 1024 * 1024; // 1 MB chunk size (adjust as needed)
|
||||
|
||||
for (let offset = 0; offset < file.length; offset += chunkSize) {
|
||||
const chunk = file.slice(offset, offset + chunkSize);
|
||||
// await this.uploadChunk(API_URL, chunk, headers);
|
||||
}
|
||||
|
||||
console.log('Upload completed.');
|
||||
}
|
||||
|
||||
async readFileInChunks(filePath: string): Promise<Uint8Array> {
|
||||
const response = await fetch(filePath);
|
||||
const reader = response.body.getReader();
|
||||
const chunks: Uint8Array[] = [];
|
||||
let done = false;
|
||||
|
||||
while (!done) {
|
||||
const { value, done: isDone } = await reader.read();
|
||||
if (!isDone) {
|
||||
chunks.push(value);
|
||||
}
|
||||
done = isDone;
|
||||
}
|
||||
|
||||
return new Uint8Array([].concat(...chunks.map((chunk) => Array.from(chunk))));
|
||||
}
|
||||
|
||||
async uploadChunk(url: string, chunks: Uint8Array[], fileName, fileExtension): Promise<void> {
|
||||
|
||||
let i = 1
|
||||
|
||||
console.log('123', chunks.length)
|
||||
for(const chunk of chunks) {
|
||||
try {
|
||||
|
||||
console.log("iterate")
|
||||
|
||||
const headers = new HttpHeaders()
|
||||
.append('X-File-Name', fileName)
|
||||
.append('X-File-Extension', fileExtension)
|
||||
.append('X-File-Content-Length', chunks.length.toString())
|
||||
.append('X-File-Index', i.toString())
|
||||
|
||||
await this.http.post('http://localhost:3001/upload', chunk.buffer, { headers, responseType: 'blob' }).toPromise();
|
||||
i++
|
||||
|
||||
} catch (error) {
|
||||
console.error('Upload error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
async uploadChunkNoLoop(url: string, chunk: Uint8Array, fileName, fileExtension, i, length): Promise<void> {
|
||||
|
||||
console.log("iterate")
|
||||
|
||||
const headers = new HttpHeaders()
|
||||
.append('X-File-Name', fileName)
|
||||
.append('X-File-Extension', fileExtension)
|
||||
.append('X-File-Content-Length', length)
|
||||
.append('X-File-Index', i.toString())
|
||||
|
||||
await this.http.post('http://localhost:3001/upload', chunk.buffer, { headers, responseType: 'blob' }).toPromise();
|
||||
|
||||
}
|
||||
|
||||
uploadChunk1(chunk: Blob, chunkNumber: number, totalChunks: number, filename: string) {
|
||||
|
||||
console.log(chunk)
|
||||
|
||||
const headers = new HttpHeaders()
|
||||
.append('X-File-Name', filename)
|
||||
.append('X-File-Content-Length', totalChunks.toString())
|
||||
.append('X-File-Index', chunkNumber.toString())
|
||||
|
||||
return this.http.post('http://localhost:3001/upload-chunk', Blob, { headers, responseType: 'blob' });
|
||||
}
|
||||
}
|
||||
|
||||
// const text = 'Hello, World00120301010asdf1002sdf 0fsdfasf0001230 12300!\n';
|
||||
// const base64 = btoa(text);
|
||||
|
||||
// let chunks = window["ChunkService"].generateChunkOfUint8Array(base64, 8)
|
||||
// window.StreamService.uploadChunk("", chunks, "peter12", "txt")
|
||||
Reference in New Issue
Block a user