clean create event page, stop video, event list box

This commit is contained in:
Peter Maquiran
2023-12-06 12:07:22 +01:00
26 changed files with 351 additions and 79 deletions
+4
View File
@@ -292,6 +292,10 @@ const routes = [
}, },
{ {
path: 'popup-question', path: 'popup-question',
loadChildren: () => import('./modals/popup-question/popup-question.module').then( m => m.PopupQuestionPageModule)
},
{
path: 'swiper',
loadChildren: () => import('./shared/swiper/swiper.module').then( m => m.SwiperPageModule) loadChildren: () => import('./shared/swiper/swiper.module').then( m => m.SwiperPageModule)
} }
+14 -3
View File
@@ -8,11 +8,11 @@ import {
HTTP_INTERCEPTORS, HTTP_INTERCEPTORS,
HttpClient, HttpClient,
} from "@angular/common/http"; } from "@angular/common/http";
import { AuthService } from '../services/auth.service';
import { Observable, throwError, BehaviorSubject, of } from "rxjs"; import { Observable, throwError, BehaviorSubject, of } from "rxjs";
import { catchError, filter, take, switchMap, tap } from "rxjs/operators"; import { catchError, filter, take, switchMap, tap } from "rxjs/operators";
import { SessionStore } from '../store/session.service'; import { SessionStore } from '../store/session.service';
import { environment } from "src/environments/environment"; import { environment } from "src/environments/environment";
import { Router } from "@angular/router";
@Injectable() @Injectable()
export class TokenInterceptor implements HttpInterceptor { export class TokenInterceptor implements HttpInterceptor {
@@ -21,7 +21,7 @@ export class TokenInterceptor implements HttpInterceptor {
null null
); );
constructor(private http: HttpClient) { } constructor(private http: HttpClient, private router: Router,) { }
intercept( intercept(
@@ -90,7 +90,18 @@ export class TokenInterceptor implements HttpInterceptor {
}), }),
catchError((error) => { catchError((error) => {
/* this.logoutUser(); */ SessionStore.user.Authorization = "";
SessionStore.user.RefreshToken = "";
SessionStore.setInativity(false)
/* SessionStore.setUrlBeforeInactivity(this.router.url); */
if (environment.production) {
window.location.pathname = '/auth'
} else {
/* const pathBeforeGoOut = window.location.pathname */
this.router.navigateByUrl('/auth', { replaceUrl: true });
}
return of(false); return of(false);
}) })
); );
+2 -2
View File
@@ -258,9 +258,9 @@
</div> </div>
<div class="schedule-details"> <div class="schedule-details">
<div class="description"> <div class="description">
<p class="m-0">{{event.event.Subject}}</p> <p class="m-0" [innerHTML]="event.event.Subject"></p>
</div> </div>
<div class="location">{{event.event.Location}}</div> <div class="location" [innerHTML]="event.event.Location"></div>
<div class="font-13 calendar-owner"*ngIf="eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId) == 'Meu calendario'">{{SessionStore.user.FullName}} </div> <div class="font-13 calendar-owner"*ngIf="eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId) == 'Meu calendario'">{{SessionStore.user.FullName}} </div>
<ng-template #other_content>{{eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId)}}</ng-template> <ng-template #other_content>{{eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId)}}</ng-template>
</div> </div>
@@ -10,6 +10,7 @@ import { ViewPublicationsPage } from './view-publications.page';
import { Attributes, IntersectionObserverHooks, LazyLoadImageModule, LAZYLOAD_IMAGE_HOOKS } from 'ng-lazyload-image'; import { Attributes, IntersectionObserverHooks, LazyLoadImageModule, LAZYLOAD_IMAGE_HOOKS } from 'ng-lazyload-image';
import { ShowMorePageModule } from 'src/app/shared/publication/view-publications/show-more/show-more.module' import { ShowMorePageModule } from 'src/app/shared/publication/view-publications/show-more/show-more.module'
import { VisibilityDirective } from 'src/app/services/directives/visibility1.directive';
export class LazyLoadImageHooks extends IntersectionObserverHooks { export class LazyLoadImageHooks extends IntersectionObserverHooks {
setup(attributes: Attributes) { setup(attributes: Attributes) {
attributes.offset = 10; attributes.offset = 10;
@@ -31,7 +32,7 @@ setup(attributes: Attributes) {
ShowMorePageModule, ShowMorePageModule,
], ],
exports: [ViewPublicationsPage], exports: [ViewPublicationsPage],
declarations: [ViewPublicationsPage], declarations: [ViewPublicationsPage, VisibilityDirective],
providers: [{provide: LAZYLOAD_IMAGE_HOOKS, useClass: LazyLoadImageHooks}] providers: [{provide: LAZYLOAD_IMAGE_HOOKS, useClass: LazyLoadImageHooks}]
}) })
export class ViewPublicationsPageModule {} export class ViewPublicationsPageModule {}
@@ -51,13 +51,30 @@
<img *ngIf="checkFileType.checkFileType(files.FileExtension ) == 'image'" class="post-img" <img *ngIf="checkFileType.checkFileType(files.FileExtension ) == 'image'" class="post-img"
[lazyLoad]="'data:image/jpg;base64,' + files.FileBase64"> [lazyLoad]="'data:image/jpg;base64,' + files.FileBase64">
<video *ngIf="checkFileType.checkFileType(files.FileExtension ) == 'video'" class="post-video" controls="controls" preload="metadata" <video [appVisibility]="onVisibilityChange" *ngIf="checkFileType.checkFileType(files.FileExtension ) == 'video'" class="post-video" controls="controls" preload="metadata"
webkit-playsinline="webkit-playsinline"> webkit-playsinline="webkit-playsinline">
<source src="{{'data:video/mp4;base64,' + files.FileBase64}}" type="video/mp4"> <source src="{{'data:video/mp4;base64,' + files.FileBase64}}" type="video/mp4">
</video> </video>
</div> </div>
</swiper-slide> </swiper-slide>
<div class="swiper-button-next"
style="
position: absolute;
background: red;
top: 50%;
">
<div>arrow-left</div>
</div>
<div class="slides-per-view"
style="
position: absolute;
background: red;
top: 50%;
">
<div>arrow-rights</div>
</div>
</swiper-container> </swiper-container>
<!-- <div *ngIf="publication.FileExtension == 'mp4'" <!-- <div *ngIf="publication.FileExtension == 'mp4'"
(click)="goToPublicationDetail(publication.DocumentId, publication.ProcessId)" class="post-video"> (click)="goToPublicationDetail(publication.DocumentId, publication.ProcessId)" class="post-video">
@@ -291,3 +291,11 @@ swiper-slide video {
justify-content: center; justify-content: center;
background: black; background: black;
} }
.swiper-container::part(button-next) {
display: none !important;
.swiper-button-next {
display: none !important;
}
}
@@ -68,6 +68,14 @@ export class ViewPublicationsPage implements OnInit {
private publicationVideoManagerService: PublicationVideoManagerService) { private publicationVideoManagerService: PublicationVideoManagerService) {
/* this.publicationVideoManagerService.setContainer(this.VideoManager.nativeElement) */
setTimeout(() => {
console.log(this.VideoManager.nativeElement)
}, 2000)
this.createPublicationList() this.createPublicationList()
this.getFromDB(); this.getFromDB();
@@ -109,6 +117,15 @@ export class ViewPublicationsPage implements OnInit {
console.log(this.publicationFolderService.publicationList[this.folderId]) console.log(this.publicationFolderService.publicationList[this.folderId])
} }
onVisibilityChange = (e: boolean) => {
console.log("nice to have", e)
if(!e) {
/* this.stopVideo() */
}
}
ngOnChanges() { ngOnChanges() {
if (typeof (this.folderId) == 'object') { if (typeof (this.folderId) == 'object') {
+43 -2
View File
@@ -24,13 +24,54 @@ export class DomSanitizerService {
} }
private encodeSpecialCharacters(input: string): string { private encodeSpecialCharacters(input: string): string {
const specialCharactersMap: Record<string, string> = {
'!': '&#33;',
'@': '&#64;',
'#': '&#35;',
'$': '&#36;',
'%': '&#37;',
'^': '&#94;',
'&': '&#38;',
'*': '&#42;',
'(': '&#40;',
')': '&#41;',
'-': '&#45;',
'_': '&#95;',
'+': '&#43;',
'=': '&#61;',
'{': '&#123;',
'}': '&#125;',
'|': '&#124;',
'\\': '&#92;',
':': '&#58;',
';': '&#59;',
'"': '&#34;',
"'": '&#39;',
'<': '&#60;',
'>': '&#62;',
',': '&#44;',
'.': '&#46;',
'?': '&#63;',
'/': '&#47;',
'ã': '&atilde;', // ã
'ç': '&ccedil;', // ç
'Â': '&Acirc;', // Â
'â': '&acirc;', // â
'Ã': '&Atilde;', // Ã
};
return input.replace(/[!@#$%^&*()-_+=\{\}|\\:;"'<>,.?/ãçÂâÃ]/g, match => specialCharactersMap[match] || match);
}
// private encodeSpecialCharacters(input: string): string {
// You can use a library like DOMPurify to encode special characters // You can use a library like DOMPurify to encode special characters
return DOMPurify.sanitize(input); // return DOMPurify.sanitize(input);
// If you don't want to use an external library, you can manually encode // 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 // Here's a simple example, you may need to extend this based on your requirements
/* return input.replace(/</g, '&lt;').replace(/>/g, '&gt;'); */ /* return input.replace(/</g, '&lt;').replace(/>/g, '&gt;'); */
} // }
/* sanitizeInput(input: string): string { /* sanitizeInput(input: string): string {
return this.sanitizer.sanitize(SecurityContext.HTML, input); return this.sanitizer.sanitize(SecurityContext.HTML, input);
@@ -15,6 +15,9 @@ export class VisibilityDirective {
threshold: 0.5 // Adjust as needed threshold: 0.5 // Adjust as needed
}; };
console.log(this.elementRef.nativeElement.parentElement, "=1=")
this.intersectionObserver = new IntersectionObserver(entries => { this.intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => { entries.forEach(entry => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
@@ -0,0 +1,8 @@
import { VisibilityDirective } from './visibility.directive';
describe('VisibilityDirective', () => {
it('should create an instance', () => {
const directive = new VisibilityDirective();
expect(directive).toBeTruthy();
});
});
@@ -0,0 +1,36 @@
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[appVisibility]'
})
export class VisibilityDirective {
intersectionObserver: IntersectionObserver;
@Input() appVisibility: (arg: any) => void;
constructor(private elementRef: ElementRef) {
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5 // Adjust as needed
};
console.log(this.elementRef.nativeElement.parentElement, "=1=")
this.intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.appVisibility(true);
} else {
this.elementRef.nativeElement.pause()
// Pause video when not visible
this.appVisibility(false); // You can implement pause logic here
}
});
}, options);
this.intersectionObserver.observe(this.elementRef.nativeElement);
}
}
@@ -16,7 +16,7 @@
<div class="main-content"> <div class="main-content">
<div class="ion-item-container" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom "> <div class="ion-item-container" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" type="text" placeholder="Assunto*" [(ngModel)]="postEvent.Subject"></ion-input> <ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*" [(ngModel)]="postEvent.Subject"></ion-input>
</div> </div>
<div *ngIf="Form && validateFrom" > <div *ngIf="Form && validateFrom" >
@@ -36,6 +36,8 @@ import { Subject } from 'rxjs';
import { TaskService } from 'src/app/services/task.service' import { TaskService } from 'src/app/services/task.service'
import { ContactsService } from 'src/app/services/contacts.service'; import { ContactsService } from 'src/app/services/contacts.service';
import { DomSanitizerService } from 'src/app/services/DomSanitizer.service'; import { DomSanitizerService } from 'src/app/services/DomSanitizer.service';
import { ChangeProfileService } from 'src/app/services/change-profile.service';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = { const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: { parse: {
dateInput: "YYYY-MMMM-DD HH:mm" dateInput: "YYYY-MMMM-DD HH:mm"
@@ -102,8 +104,6 @@ export class NewEventPage implements OnInit {
documents: SearchList[] = []; documents: SearchList[] = [];
// minDate: string;
loggeduser: LoginUserRespose; loggeduser: LoginUserRespose;
@ViewChild('picker') picker: any; @ViewChild('picker') picker: any;
@ViewChild('fim') fim: any; @ViewChild('fim') fim: any;
@@ -148,7 +148,8 @@ export class NewEventPage implements OnInit {
private processeService: ProcessesService, private processeService: ProcessesService,
public TaskService: TaskService, public TaskService: TaskService,
private contactsService: ContactsService, private contactsService: ContactsService,
private domSanitazerService: DomSanitizerService private domSanitazerService: DomSanitizerService,
private changeProfileService: ChangeProfileService,
) { ) {
this.dateAdapter.setLocale('pt'); this.dateAdapter.setLocale('pt');
this.loggeduser = SessionStore.user; this.loggeduser = SessionStore.user;
@@ -158,6 +159,10 @@ export class NewEventPage implements OnInit {
ngOnInit() { ngOnInit() {
this.changeProfileService.registerCallback(() => {
this.initializeData()
})
if (!this.CalendarName) { if (!this.CalendarName) {
if (this.eventService.calendarNamesAry.includes('Meu calendario')) { if (this.eventService.calendarNamesAry.includes('Meu calendario')) {
this.CalendarName = 'Meu calendario'; this.CalendarName = 'Meu calendario';
@@ -172,6 +177,37 @@ export class NewEventPage implements OnInit {
this.eventBody = { BodyType: "1", Text: "" }; this.eventBody = { BodyType: "1", Text: "" };
this.postEvent.Body = this.eventBody; this.postEvent.Body = this.eventBody;
this.initializeData()
if (this.postEvent.Attendees != null) {
this.postEvent.Attendees.forEach(e => {
if (e.IsRequired) {
this.taskParticipants.push(e);
} else {
this.taskParticipantsCc.push(e);
}
})
}
console.log('Attendes',this.taskParticipants)
this.taskParticipants = removeDuplicate(this.taskParticipants);
this.taskParticipantsCc = removeDuplicate(this.taskParticipantsCc);
this.setIntervenient.emit(this.taskParticipants);
this.setIntervenientCC.emit(this.taskParticipantsCc);
this.setDefaultTime();
}
this.date = new Date(2021, 9, 4, 5, 6, 7);
this.injectValidation();
this.changeAgenda()
this.fetchContacts("")
}
initializeData() {
if (this.selectedSegment != "Combinada") { if (this.selectedSegment != "Combinada") {
this.postEvent = { this.postEvent = {
EventId: '', EventId: '',
@@ -216,33 +252,6 @@ export class NewEventPage implements OnInit {
EventRecurrence: { Type: '-1', LastOccurrence: this.autoEndTime }, EventRecurrence: { Type: '-1', LastOccurrence: this.autoEndTime },
} }
} }
if (this.postEvent.Attendees != null) {
this.postEvent.Attendees.forEach(e => {
if (e.IsRequired) {
this.taskParticipants.push(e);
} else {
this.taskParticipantsCc.push(e);
}
})
}
console.log('Attendes',this.taskParticipants)
this.taskParticipants = removeDuplicate(this.taskParticipants);
this.taskParticipantsCc = removeDuplicate(this.taskParticipantsCc);
this.setIntervenient.emit(this.taskParticipants);
this.setIntervenientCC.emit(this.taskParticipantsCc);
this.setDefaultTime();
}
this.date = new Date(2021, 9, 4, 5, 6, 7);
this.injectValidation();
this.changeAgenda()
this.fetchContacts("")
} }
setDefaultTime() { setDefaultTime() {
@@ -13,7 +13,7 @@
</button> </button>
</div> </div>
<div class="middle" (click)="openOptions()"> <div class="middle" (click)="openOptions()">
<p class="title">{{loadedEvent.Subject}}</p> <p class="title" [innerHTML]="loadedEvent.Subject"></p>
</div> </div>
<div class="div-icon d-flex align-base"> <div class="div-icon d-flex align-base">
@@ -54,7 +54,7 @@
<div class="upper-content"> <div class="upper-content">
<div class="content-location"> <div class="content-location">
<span class="date">{{loadedEvent.Location}}</span> <span class="date" [innerHTML]="loadedEvent.Location"></span>
<div *ngIf="loadedEvent.Organizer"> <div *ngIf="loadedEvent.Organizer">
@@ -199,7 +199,7 @@ export class NewPublicationPage implements OnInit {
multiple: true, multiple: true,
}); });
result.files.forEach(async element => { result.files.forEach(async element => {
if(this.checkFileType.checkFileType(element.mimeType) == 'image') { if(this.checkFileType.checkFileType(element.mimeType) == 'image' || this.checkFileType.checkFileType(element.mimeType) == 'video') {
this.convertBlobToBase64(element.blob).then((value) => { this.convertBlobToBase64(element.blob).then((value) => {
console.log(element.mimeType) console.log(element.mimeType)
@@ -35,7 +35,7 @@
</ion-refresher-content> </ion-refresher-content>
</ion-refresher> </ion-refresher>
<div class="main-container px-20" *ngIf="publicationFolderService.FolderDetails[folderId]"> <div class="main-container px-20" *ngIf="publicationFolderService.FolderDetails[folderId]" >
<p class="item-content-detail">{{publicationFolderService.FolderDetails[folderId].Detail}}</p> <p class="item-content-detail">{{publicationFolderService.FolderDetails[folderId].Detail}}</p>
@@ -56,6 +56,24 @@
</div> </div>
</swiper-slide> </swiper-slide>
<div class="swiper-button-next"
style="
position: absolute;
background: red;
top: 50%;
">
<div>arrow-left</div>
</div>
<div class="slides-per-view"
style="
position: absolute;
background: red;
top: 50%;
right: 0px;
">
<div>arrow-rights</div>
</div>s
</swiper-container> </swiper-container>
<div class="post-content"> <div class="post-content">
@@ -60,6 +60,15 @@ export class ViewPublicationsPage implements OnInit {
private publicationVideoManagerService: PublicationVideoManagerService private publicationVideoManagerService: PublicationVideoManagerService
) { ) {
setTimeout(() => {
document.querySelector("swiper-container").shadowRoot.querySelector(".swiper-button-next").innerHTML = "ok"
alert("ok")
// console.log("this.VideoManager", this.VideoManager, document.querySelector('.VideoManager'))
/* this.publicationVideoManagerService.setContainer(this.VideoManager.nativeElement) */
}, 15000)
// this.publicationVideoManagerService.setContainer(this.VideoManager.nativeElement)
this.createPublicationList() this.createPublicationList()
} }
@@ -69,7 +78,7 @@ export class ViewPublicationsPage implements OnInit {
console.log("nice to have", e) console.log("nice to have", e)
if(!e) { if(!e) {
//this.stopVideo() /* this.stopVideo() */
} }
} }
ngOnInit() { ngOnInit() {
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SwiperPage } from './swiper.page';
const routes: Routes = [
{
path: '',
component: SwiperPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class SwiperPageRoutingModule {}
+20
View File
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { SwiperPageRoutingModule } from './swiper-routing.module';
import { SwiperPage } from './swiper.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
SwiperPageRoutingModule
],
declarations: [SwiperPage]
})
export class SwiperPageModule {}
+9
View File
@@ -0,0 +1,9 @@
<ion-header>
<ion-toolbar>
<ion-title>swiper</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
</ion-content>
+24
View File
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { SwiperPage } from './swiper.page';
describe('SwiperPage', () => {
let component: SwiperPage;
let fixture: ComponentFixture<SwiperPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ SwiperPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(SwiperPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
+15
View File
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-swiper',
templateUrl: './swiper.page.html',
styleUrls: ['./swiper.page.scss'],
})
export class SwiperPage implements OnInit {
constructor() { }
ngOnInit() {
}
}
+1 -1
View File
@@ -779,7 +779,7 @@ app-header-no-search .ion-toolbar{
--header-bottom-line-background-image: linear-gradient(270deg, var(--color2) 0%, var(--color3) 23.44%, var(--color4) 78.13%, var(--color5) 100%) !important; --header-bottom-line-background-image: linear-gradient(270deg, var(--color2) 0%, var(--color3) 23.44%, var(--color4) 78.13%, var(--color5) 100%) !important;
--title-text-color: rgb(0, 0, 0); --title-text-color: rgb(0, 0, 0);
--subtitle-text-color: #000 --subtitle-text-color: #000;
+5
View File
@@ -118,6 +118,11 @@ $app-theme: mat-light-theme(
--ion-color-primary-contrast: black; --ion-color-primary-contrast: black;
--swiper-theme-color: #ffb703;
--swiper-navigation-color: #ffb703;
--swiper-pagination-color: #ffb703;
} }
// dark-mode // dark-mode