fix change folder path

This commit is contained in:
Peter Maquiran
2024-08-16 14:21:01 +01:00
parent bec5104ac8
commit 6072a2456b
114 changed files with 419 additions and 540 deletions
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddUserPage } from './add-user.page';
const routes: Routes = [
{
path: '',
component: AddUserPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AddUserPageRoutingModule {}
@@ -1,20 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { AddUserPageRoutingModule } from './add-user-routing.module';
import { AddUserPage } from './add-user.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
AddUserPageRoutingModule
],
declarations: [AddUserPage]
})
export class AddUserPageModule {}
@@ -1,9 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-title>addUser</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
</ion-content>
@@ -1,24 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { AddUserPage } from './add-user.page';
describe('AddUserPage', () => {
let component: AddUserPage;
let fixture: ComponentFixture<AddUserPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ AddUserPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(AddUserPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-add-user',
templateUrl: './add-user.page.html',
styleUrls: ['./add-user.page.scss'],
})
export class AddUserPage implements OnInit {
constructor() { }
ngOnInit() {
}
}
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EditGroupPage } from './edit-group.page';
const routes: Routes = [
{
path: '',
component: EditGroupPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EditGroupPageRoutingModule {}
@@ -1,26 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EditGroupPageRoutingModule } from './edit-group-routing.module';
import { EditGroupPage } from './edit-group.page';
import { SharedModule } from '../../shared.module';
import { BtnSeguintePageModule } from '../../btn-seguinte/btn-seguinte.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EditGroupPageRoutingModule,
BtnSeguintePageModule,
],
exports: [EditGroupPage],
declarations: [EditGroupPage]
})
export class EditGroupPageModule {}
@@ -1,44 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="left">
<button class="btn-no-color" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/doneIt/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/iassets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="middle">
<ion-label class="title">Alterar assunto</ion-label>
</div>
<app-btn-seguinte (click)="changeGroupName()"></app-btn-seguinte>
</div>
</div>
</ion-toolbar>
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
</ion-header>
<ion-content class="width-100">
<div class="main-content d-flex width-100">
<div class="item-container d-flex flex-column width-100">
<ion-input [(ngModel)]="groupName" placeholder="Título"></ion-input>
</div>
<div *ngIf="false" class="item-container-no-border">
<ion-checkbox (ionChange)="_ionChange($event)" color="primary"></ion-checkbox>
<ion-label>Grupo Ultra-secreto</ion-label>
</div>
<div *ngIf="showDuration" class="container-div width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-duration.svg"></ion-icon>
</div>
<div class="ion-input-class">
<ion-input (click)="showPicker()" [(ngModel)]="displayDuration" placeholder="Duração"></ion-input>
</div>
</div>
</div>
</div>
</ion-content>
@@ -1,151 +0,0 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.div-top-header{
//width: 400px;
margin: 0 auto;
background-color: #0782c9;
overflow: auto;
padding-top: 15px;
border: 0!important;
.div-search{
font-size: rem(45);
float: left;
margin: 0 0 0 10px
}
.div-logo{
background: transparent;
width: 140px;
margin: 5px 0 0px 71px;
float: left;
}
.div-logo img{
width: 100%;
}
.div-profile{
font-size: rem(45);
float: right;
margin-right: 10px;
}
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
//width: 360px;
margin: 0px auto;
overflow: auto;
padding: 0 !important;
background: #fff;
.left{
width: 37px;
float: left;
font-size: rem(35);
overflow: auto;
}
.middle{
padding: 0!important;
float: left;
width: 221px;
margin: 2.5px 0 0 5px;
}
.right{
padding: 0!important;
float: right;
font-size: rem(15);
color: #0782c9;
margin: 8px 0 0 5px;
}
}
.title{
font-size: rem(25);
}
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
}
.main-content{
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 15px 20px 0 20px;
.item-container{
//width: 360px;
margin: 15px auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.item-container-no-border{
display: flex;
//width: 360px;
margin: 25px auto;
border-radius: 5px;
align-items: center;
}
.item-container-no-border ion-label{
padding-left: 10px;
font-size: rem(12);
color: #000;
}
}
.container-div{
margin-bottom: 15px;
overflow: auto;
.ion-item-class-2{
//width: 360px;
margin: 0px auto;
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
}
.ion-input-class{
width: calc(100% - 45px);
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
}
}
@@ -1,24 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EditGroupPage } from './edit-group.page';
describe('EditGroupPage', () => {
let component: EditGroupPage;
let fixture: ComponentFixture<EditGroupPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ EditGroupPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EditGroupPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,220 +0,0 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ModalController, PickerController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
import { HttpResponse } from '@microsoft/signalr';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { ToastService } from 'src/app/services/toast.service';
import { ZodError } from 'zod';
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service'
@Component({
selector: 'app-edit-group',
templateUrl: './edit-group.page.html',
styleUrls: ['./edit-group.page.scss'],
})
export class EditGroupPage implements OnInit {
showLoader: boolean;
displayDuration: any;
showDuration: boolean;
selectedDuration = ['','',''];
groupName:string;
room:any;
loggedUser: any;
@Input() roomId:string;
@Output() openGroupContacts:EventEmitter<any> = new EventEmitter<any>();
@Output() openGroupMessage:EventEmitter<any> = new EventEmitter<any>();
@Output() closeAllDesktopComponents:EventEmitter<any> = new EventEmitter<any>();
constructor(
private modalController: ModalController,
private pickerController: PickerController,
private chatService: ChatService,
public ThemeService: ThemeService,
private RoomRepositoryService: RoomRepositoryService,
private httpErrorHandle: HttpErrorHandle,
private toastService: ToastService,
) {
this.loggedUser = SessionStore.user.ChatData['data'];
}
ngOnInit() {
// this.chatService.refreshtoken();
this.getRoomInfo();
}
getRoomInfo(){
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
this.room = room['room'];
try {
this.groupName = this.room.name.split('-').join(' ');
} catch (error) {
this.groupName = this.room.name;
}
});
}
close() {
//this.modalController.dismiss();
this.closeAllDesktopComponents.emit();
this.openGroupMessage.emit(this.roomId);
}
async changeGroupName() {
this.showLoader = true
const result = await this.RoomRepositoryService.updateRoomBy({
roomId: this.roomId,
roomName: this.groupName,
roomType: 0
})
if(result.isOk()) {
this.openGroupMessage.emit(this.roomId);
} else if (result.error instanceof HttpResponse) {
this.httpErrorHandle.httpStatusHandle(result.error)
} else if (result.error instanceof ZodError) {
this.toastService._badRequest("Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.")
console.log(result.error.errors)
} else {
this.toastService._badRequest("Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.")
console.log(result.error)
}
this.showLoader = false
}
updateGroup() {
this.showLoader = true;
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
this.room = room['room'];
this.showLoader = false;
this.openGroupMessage.emit(this.room._id);
});
}
_ionChange(event){
this.showDuration = event.detail.checked;
}
async showPicker(){
const picker = await this.pickerController.create({
cssClass: '',
buttons: [
{
text: 'Cancelar', role: 'cancel', cssClass: 'btn-cancel'
},
{
text: 'Ok',
cssClass: 'btn-cancel',
handler:(value:any)=>{
this.selectedDuration = [
value.days.value,
value.hours.value,
value.minutes.value,
]
if(value.days.value != null && value.hours.value != null && value.minutes.value != null){
if(value.days.value > 0){
if(value.days.value == 1){
if(value.hours.value == 1){
this.displayDuration = value.days.value + " day " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
else{
if(value.hours.value == 1){
this.displayDuration = value.days.value + " days " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
}
else{
if(value.hours.value == 1){
this.displayDuration = value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
}
},
},
],
columns: [
{
name: 'days',
prefix: 'Dias',
options: [
{ text: '0', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
]
},
{
name: 'hours',
prefix: 'Horas',
options: [
{ text: '0', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
{ text: '5', value: 5 },
{ text: '6', value: 6 },
{ text: '7', value: 7 },
{ text: '8', value: 8 },
]
},
{
name: 'minutes',
prefix: 'Minutos',
selectedIndex: 0,
options: [
{ text: '5', value: 5 },
{ text: '10', value: 10 },
{ text: '15', value: 15 },
{ text: '20', value: 20 },
{ text: '25', value: 25 },
{ text: '30', value: 30 },
{ text: '35', value: 35 },
{ text: '45', value: 45 },
{ text: '50', value: 50 },
{ text: '55', value: 55 },
]
}
]
});
await picker.present();
picker.onDidDismiss().then(async data =>{
let day = await picker.getColumn('days');
let hour = await picker.getColumn('hours');
let minutes = await picker.getColumn('minutes');
});
}
}
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmptyChatPage } from './empty-chat.page';
const routes: Routes = [
{
path: '',
component: EmptyChatPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EmptyChatPageRoutingModule {}
@@ -1,21 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EmptyChatPageRoutingModule } from './empty-chat-routing.module';
import { EmptyChatPage } from './empty-chat.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EmptyChatPageRoutingModule
],
exports: [EmptyChatPage],
declarations: [EmptyChatPage]
})
export class EmptyChatPageModule {}
@@ -1,5 +0,0 @@
<ion-content>
<div class="center height-100">
<p>{{texto}}</p>
</div>
</ion-content>
@@ -1,5 +0,0 @@
.center {
display: flex;
justify-content: center;
align-items: center;
}
@@ -1,24 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EmptyChatPage } from './empty-chat.page';
describe('EmptyChatPage', () => {
let component: EmptyChatPage;
let fixture: ComponentFixture<EmptyChatPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ EmptyChatPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EmptyChatPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,16 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-empty-chat',
templateUrl: './empty-chat.page.html',
styleUrls: ['./empty-chat.page.scss'],
})
export class EmptyChatPage implements OnInit {
@Input() texto:string;
constructor() { }
ngOnInit() {
}
}
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { GroupContactsPage } from './group-contacts.page';
const routes: Routes = [
{
path: '',
component: GroupContactsPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class GroupContactsPageRoutingModule {}
@@ -1,26 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { GroupContactsPageRoutingModule } from './group-contacts-routing.module';
import { GroupContactsPage } from './group-contacts.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { PipesModule } from 'src/app/pipes/pipes.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
GroupContactsPageRoutingModule,
PipesModule,
],
exports: [GroupContactsPage],
declarations: [GroupContactsPage]
})
export class GroupContactsPageModule {}
@@ -1,66 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header width-100">
<div class="title-content width-100">
<div class="back-icon cursor-pointer">
<button title="Retroceder" class="btn-no-color" (click)="openGroupMessagesPage()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/doneIt/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="div-title">
<ion-label class="title">Contactos</ion-label>
</div>
<div>
<button class="btn-no-color adicionar" (click)="updateGroup()">
<ion-label>Adicionar</ion-label>
</button>
</div>
</div>
</div>
</ion-toolbar>
<ion-toolbar class="toolbar-search">
<div class="search">
<ion-searchbar search-icon="undefined" debounce="500" (ionChange)="onChange($event)" placeholder="Pesquisar por contacto" ></ion-searchbar>
</div>
</ion-toolbar>
</ion-header>
<ion-content class="width-100">
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content width-100">
<div class="members" *ngIf="currentMembers">
<ion-label class="members-label">Contactos selecção:</ion-label>
<ion-list class="members-list" *ngFor="let user of currentMembers">
<div class="members-checkbox" [class.inactive]="SessionStore.user.UserName == user.username">
<ion-checkbox disabled checked color="primary"></ion-checkbox>
<p class="ma-0">{{user.wxFullName }}</p>
<ion-icon name="ellipse"></ion-icon>
<button (click)="deleteMember(user)" class="btn-no-color detele-item-icon">
<ion-icon color="danger" name="close"></ion-icon>
</button>
</div>
</ion-list>
</div>
<div *ngFor="let userContainer of userContainer | keyvalue;" >
<div class="item-divider">
<ion-label>{{ userContainer.key }}</ion-label>
</div>
<div *ngFor="let user of userContainer.value; let i = index" class="d-flex px-20 align-center">
<ion-checkbox [(ngModel)]="user.isChecked" (ionChange)="onChangeCheckBox(user)" color="primary"></ion-checkbox>
<ion-label class="flex-grow-1 px-10">{{user.wxFullName}}</ion-label>
<div class="icon"><ion-icon name="ellipse"></ion-icon></div>
</div>
</div>
</div>
</ion-content>
@@ -1,184 +0,0 @@
@import '~src/function.scss';
.header-toolbar{
--background:transparent;
--opacity: 1;
.main-header{
height: 100%;
font-family: Roboto;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
.title-content{
margin: 0px auto;
overflow: auto;
padding: 0 !important;
}
.back-icon{
width: 37px;
float: left;
font-size: rem(35);
overflow: auto;
}
.div-title{
width: 221px;
padding: 0!important;
float: left;
margin: 2.5px 0 0 5px;
}
.adicionar{
padding: 0!important;
float: right;
font-size: rem(15);
color: var(--font-awesome);
margin: 8px 5px 0 5px;
}
.title{
font-size: rem(25);
}
}
}
.toolbar-search{
--padding-top:0 !important;
--padding-bottom:0 !important;
--padding-start:0 !important;
--padding-end:0 !important;
.search{
border: 1px solid #ebebeb;
margin: 5px 20px 5px 20px;
border-radius: 5px;
}
.search ion-searchbar{
width: 100%;
margin: 0 !important;
padding: 0 !important;
--border-radius: 5px;
--box-shadow: none;
overflow: hidden;
--icon-color:var(--font-awesome);
}
}
ion-content{
--background:transparent;
}
.main-content{
//width: 100%;
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
padding: 0 0 0 0;
overflow:auto;
.members{
padding: 15px 20px 0 20px !important;
.members-list{
margin: 0 !important;
padding: 0 !important;
}
}
.members-label{
//margin: 10px 20px 10px 20px !important;
/* font-size: rem(15); */
font-weight: bold;
}
.members-checkbox{
display: flex;
//margin: 0px 20px 0px 20px !important;
overflow: auto;
align-items: center;
.detele-item-icon{
display: none;
width: rem(30);
margin-left: 15px;
}
.detele-item-icon ion-icon{
font-size: rem(20) !important;
}
}
.members-checkbox:hover{
.detele-item-icon{
display: flex;
justify-content: flex-end;
}
}
.item-divider{
background: #ebebeb;
font-size: rem(15);
margin: 10px 0 10px 0;
padding:5px 0 5px 20px;
}
.item-checkbox{
display: flex;
margin: 10px 20px 10px 20px !important;
overflow: auto;
}
.item-checkbox ion-checkbox, .members-checkbox ion-checkbox{
--border-color: var(--title-text-color);
--background-checked:var(--title-text-color);
float: left;
}
.item-checkbox ion-label, .members-checkbox p{
padding-left: 10px;
font-size: rem(15);
color: var(--title-text-color);
float: left;
flex-grow: 1;
}
.icon, .members-checkbox ion-icon{
font-size: rem(10);
}
.online{
color:#99e47b !important;
}
.offline{
color:#cbced1 !important;
}
.away{
color:#ffd21f !important;
}
.invisible{
color:#cbced1 !important;
}
.busy{
color:#f5455c !important;
}
}
.inactive {
opacity: 0.7;
button {
display: none !important;
}
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { GroupContactsPage } from './group-contacts.page';
describe('GroupContactsPage', () => {
let component: GroupContactsPage;
let fixture: ComponentFixture<GroupContactsPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GroupContactsPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(GroupContactsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,226 +0,0 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ThemeService } from 'src/app/services/theme.service'
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { SessionStore } from 'src/app/store/session.service';
import { HttpRequest } from '@angular/common/http';
import { ZodError } from 'zod';
import { HttpResponse } from '@microsoft/signalr';
import { ToastService } from 'src/app/services/toast.service';
@Component({
selector: 'app-group-contacts',
templateUrl: './group-contacts.page.html',
styleUrls: ['./group-contacts.page.scss'],
})
export class GroupContactsPage implements OnInit {
showLoader: boolean;
textSearch:string;
@Input() roomId:string;
@Output() openGroupMessage:EventEmitter<any> = new EventEmitter<any>();
@Output() openGroupContacts:EventEmitter<any> = new EventEmitter<any>();
currentMembers:UserContacts[];
allChatUsers: UserContacts[] = [];
userContainer: {[key: string]: ( UserContacts & {isChecked: boolean})[] } = {}
selectedUsers: number[] =[]
SessionStore = SessionStore
constructor(
public ThemeService: ThemeService,
private contactsRepositoryService: ContactRepositoryService,
private RoomRepositoryService: RoomRepositoryService,
private httpErrorHandle: HttpErrorHandle,
private toastService: ToastService,
){}
ngOnInit(): void {
this.loadUsers()
}
get hasMemberToUpload() {
return this.selectedUsers.length >= 1
}
async updateGroup() {
if(this.hasMemberToUpload) {
this.showLoader = true;
const addMembers = await this.RoomRepositoryService.addMemberToRoom({
id: this.roomId,
members: this.selectedUsers
})
if(addMembers.isOk()) {
console.log('addMembers', addMembers)
// this.addContacts(this.roomId);
this.openGroupMessage.emit(this.roomId);
this.RoomRepositoryService.getRoomById(this.roomId);
} else if(addMembers.error instanceof HttpRequest) {
this.httpErrorHandle.httpStatusHandle(addMembers.error)
}
} else {
this.openGroupMessage.emit(this.roomId);
}
this.showLoader = false;
}
openGroupMessagesPage() {
this.openGroupMessage.emit(this.roomId)
}
async loadUsers() {
const getallChatUsers = await this.contactsRepositoryService.getUsers()
const getRoomById = await this.RoomRepositoryService.getRoomById(this.roomId)
console.log({getallChatUsers, getRoomById})
if(getallChatUsers.isOk() && getRoomById.isOk()) {
this.allChatUsers = getallChatUsers.value.data.result.sort((a,b) => {
if(a.wxFullName < b.wxFullName) {
return -1;
}
if(a.wxFullName > b.wxFullName) {
return 1;
}
return 0;
});
const currentMemberToMap = await this.RoomRepositoryService.getRoomMemberById(this.roomId)
console.log({currentMemberToMap})
this.currentMembers = currentMemberToMap.map((e)=> ({
userPhoto: e.userPhoto,
wxeMail: e.wxeMail,
wxFullName: e.wxFullName,
wxUserId: e.wxUserId
}))
const currentMemberIds = this.currentMembers.map(e => e.wxUserId)
const allSelectableUsers = this.allChatUsers.filter(e => !currentMemberIds.includes(e.wxUserId))
for(const user of allSelectableUsers) {
const firstLetter = user.wxFullName.charAt(0)
if(!this.userContainer[firstLetter]) {
user['isChecked'] = false
this.userContainer[firstLetter] = [user as any]
} else {
const userIds = this.userContainer[firstLetter].map( e => e.wxUserId)
if(!userIds.includes(user.wxUserId)) {
user['isChecked'] = false
this.userContainer[firstLetter].push(user as any)
}
}
}
}
else if (getRoomById.isErr() && getRoomById.error instanceof HttpResponse) {
this.httpErrorHandle.httpStatusHandle(getRoomById.error)
} else if (getallChatUsers.isErr() && getallChatUsers.error instanceof HttpResponse) {
this.httpErrorHandle.httpStatusHandle(getallChatUsers.error)
} else if (getRoomById.isErr() ) {
console.log(getRoomById.error)
} else if (getallChatUsers.isErr() ) {
console.log(getallChatUsers.error)
} else {
this.toastService._badRequest("Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.")
}
this.showLoader = false;
}
doRefresh(ev) {
ev.target.complete();
}
FilterUserListedByTextSearch() {
return this.allChatUsers.filter( e => e.wxFullName.toLowerCase().includes(this.textSearch.toLowerCase())).sort((a,b) => {
if(a.wxFullName < b.wxFullName) {
return -1;
}
if(a.wxFullName > b.wxFullName) {
return 1;
}
return 0;
});
}
onChangeCheckBox(user: UserContacts & {isChecked: boolean}) {
if(user.isChecked) {
this.selectedUsers.push(user.wxUserId)
} else {
this.selectedUsers = this.selectedUsers.filter(e => e!= user.wxUserId)
}
}
onChange(event) {
this.textSearch = event.detail.value;
const filteredUserList: (UserContacts & {isChecked: boolean})[] = this.FilterUserListedByTextSearch() as any
const userContainer = {}
for(const user of filteredUserList) {
const firstLetter = user.wxFullName.charAt(0)
if(!userContainer[firstLetter]) {
user.isChecked = this.selectedUsers.includes(user.wxUserId)
userContainer[firstLetter] = [user]
} else {
user.isChecked = this.selectedUsers.includes(user.wxUserId)
userContainer[firstLetter].push(user)
}
}
this.userContainer = userContainer
}
async deleteMember(user: UserContacts) {
this.showLoader = true;
const result = await this.RoomRepositoryService.removeMemberToRoom({
id: this.roomId,
members: [ user.wxUserId]
})
if(result.isOk()) {
this.currentMembers = this.currentMembers.filter( e => e.wxUserId != user.wxUserId)
const firstLetter = user.wxFullName.charAt(0)
if(!this.userContainer[firstLetter]) {
user['isChecked'] = false
this.userContainer[firstLetter] = [user as any]
} else {
user['isChecked'] = false
this.userContainer[firstLetter].push(user as any)
}
} else if(result.error instanceof HttpRequest) {
this.httpErrorHandle.httpStatusHandle(result.error)
} else if(result.error instanceof ZodError) {
console.log(result.error.issues)
}
this.showLoader = false;
}
}
@@ -1,21 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { GroupMessagesPage } from './group-messages.page';
const routes: Routes = [
{
path: '',
component: GroupMessagesPage
},
{
path: 'group-contacts',
loadChildren: () => import('./group-contacts/group-contacts.module').then( m => m.GroupContactsPageModule)
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
@@ -1,37 +0,0 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { GroupMessagesPageRoutingModule } from './group-messages-routing.module';
import { GroupMessagesPage } from './group-messages.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { ChatPopoverPageModule } from '../../popover/chat-popover/chat-popover.module';
import { NewEventPageModule } from '../../agenda/new-event/new-event.module';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import {MatMenuModule} from '@angular/material/menu';
import { LettersAvatarModule } from "ngx-letters-avatar";
import { PipesModule } from 'src/app/pipes/pipes.module';
import { SafehtmlPipe } from 'src/app/pipes/safehtml.pipe';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
FontAwesomeModule,
ChatPopoverPageModule,
GroupMessagesPageRoutingModule,
MatMenuModule,
LettersAvatarModule,
PipesModule,
//
],
exports: [GroupMessagesPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [GroupMessagesPage]
})
export class GroupMessagesPageModule {}
@@ -1,326 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="header-top">
<div class="middle">
<!-- <ion-label class="title">{{ ChatSystemService.getGroupRoom(roomId).name.split('-').join(' ') }}</ion-label> -->
</div>
<div class="right">
<!-- <div (click)=" ChatSystemService.getGroupRoom(this.roomId).deleteAll()">delete all</div> -->
<button title="Menu" class="btn-no-color" (click)="openGroupMessagesOptions()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg"></ion-icon>
</button>
</div>
</div>
<div title="Ver Contactos" (click)="openGroupContactsPage()" class="header-bottom">
<div class="header-bottom-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
</div>
<!-- <div class="header-bottom-contacts" *ngIf="ChatSystemService.getGroupRoom(roomId)">
<ion-label class="contacts-list" *ngFor="let member of ChatSystemService.getGroupRoom(roomId).membersExcludeMe; let last = last" >
{{member.name}}<span *ngIf="!last">, </span>
</ion-label>
</div> -->
</div>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="messages" #scrollMe>
<div class="welcome-text">
<ion-label> Esta conversa passou a grupo</ion-label><br />
<ion-label>A conversa original mantêm-se como chat individual</ion-label>
</div>
<div class="messages-list-item-wrapper container-width-100" *ngFor="let msg of []; let last = last">
<div class="message-item incoming-{{msg.u.username!=sessionStore.user.UserName}} max-width-45" *ngIf="msg.t != 'r' && msg.t != 'ul' && msg.t != 'au' && msg.t != 'ru' && msg.msg !=''" [class.dateLabel]="msg.dateLabel">
<div class="message-item-options d-flex justify-content-end" *ngIf="!msg.dateLabel">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
</mat-menu>
</div>
<div class="title d-flex" *ngIf="!msg.dateLabel">
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.time}}</span>
</div>
<div class="message">
<pre *ngIf="msg.delate == false" class="message-box text ma-0 font-13-rem" style="font-size: 0.8125rem !important;" >{{msg.msg}}</pre>
<pre *ngIf="msg.delate == true" class="message-box text ma-0 font-13-rem" style="font-size: 0.8125rem !important;" >{{msg.msg}}</pre>
<ion-label class="float-status-all float-status" *ngIf="msg.u.username==sessionStore.user.UserName">
<span *ngIf="msg.online == true && !msg.manualRetry && msg.viewed == 0" class="enviado pl-10"> Enviado</span>
<!-- <ion-icon *ngIf="msg.messageSend == false && !msg.manualRetry" src="assets/images/clock-regular.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0 && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon> -->
<span class="lido pl-10" *ngIf="msg.viewed.length >= 1" > Lido</span>
<div *ngIf="msg.manualRetry" class="try pl-10" (click)="msg.send()">Tentar</div>
</ion-label>
{{last ? scrollToBottom() : ''}}
</div>
</div>
<div *ngIf="msg.file">
<div class="message-item incoming-{{msg.u.username!=sessionStore.user.UserName}} max-width-45" *ngIf="msg.t != 'r' && msg.t != 'ul' && msg.t != 'au' && msg.t != 'ru' && msg.file.type != 'application/meeting'" >
<div *ngIf="msg.file.type != 'application/meeting'">
<div class="message-item-options d-flex justify-content-end">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
</mat-menu>
</div>
<div class="title d-flex">
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.time}}</span>
</div>
<div class="message">
<div *ngIf="msg.attachments" class="message-attachments">
<div *ngFor="let file of msg.attachments">
<div *ngIf="msg.file.type == 'application/img' && !msg.attachments[0].image_url" (click)="openPreview(msg)">
<div *ngIf="!msg.attachments[0].image_url">
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
<ion-icon name="image" class="file-icon"></ion-icon>
<ion-label>{{"Imagem"}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && msg.downloadLoader == false && msg.uploadingFile == false && msg.downloadAttachmentsTemp == 0" class="icon-download" src="assets/icon/theme/{{ThemeService.currentTheme}}/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="( msg.downloadLoader == true || msg.uploadingFile == true )" class="icon-download" src="assets/gif/theme/{{ThemeService.currentTheme}}/Blocks-loader.svg" slot="end"></ion-icon>
<ion-icon *ngIf="msg.downloadAttachments == false && msg.downloadAttachmentsTemp >= 1 && msg.downloadLoader == false" src="assets/images/retry-svgrepo-com.svg" class="icon-download font-12"> </ion-icon>
</ion-item>
</div>
</div>
<div *ngIf="msg.file.type == 'application/img' &&
msg.attachments[0].image_url" (click)="openPreview(msg)">
<img class="d-block" *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image">
<ion-icon *ngIf="msg.attachments[0].image_url == null" name="download-outline"></ion-icon>
<ion-label class="float-status-all float-status" *ngIf="msg.u.username==sessionStore.user.UserName">
<span *ngIf="msg.online == true && !msg.manualRetry && msg.viewed == 0" class="enviado pl-10"> Enviado</span>
<!-- <ion-icon *ngIf="msg.messageSend == false && !msg.manualRetry" src="assets/images/clock-regular.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0 && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon> -->
<span class="lido pl-10" *ngIf="msg.viewed.length >= 1" >Lido</span>
<div *ngIf="msg.manualRetry" class="try pl-10" (click)="msg.send()"> Tentar</div>
</ion-label>
</div>
<div *ngIf="msg.file.type != 'application/img'">
<div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color">
<div (click)="openPreview(msg)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
<div *ngIf="!msg.attachments[0].image_url">
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
<ion-icon *ngIf="msg.attachments[0].type != 'webtrix'" name="document" class="file-icon"></ion-icon>
<ion-icon *ngIf="msg.attachments[0].type == 'webtrix'" src="assets/icon/webtrix.svg" class="file-icon"></ion-icon>
<ion-label>{{ file.title}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' && msg.attachments[0].type != 'webtrix' && !( msg.downloadLoader == true || msg.uploadingFile == true ) " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && msg.attachments[0].type != 'webtrix' && !( msg.downloadLoader == true || msg.uploadingFile == true ) " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="( msg.downloadLoader == true || msg.uploadingFile == true )" class="icon-download" src="assets/gif/theme/{{ThemeService.currentTheme}}/Blocks-loader.svg" slot="end"></ion-icon>
</ion-item>
</div>
<div *ngIf="msg.attachments[0].image_url">
<span *ngIf="msg.file.type">
<fa-icon *ngIf="msg.file.type == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-icon"></fa-icon>
<fa-icon *ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'" icon="file-word" class="word-icon"></fa-icon>
<fa-icon *ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'" icon="file-word" class="excel-icon"></fa-icon>
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-icon>
</span>
<ion-label class="file-title">{{file.title}}</ion-label>
</div>
</div>
</div>
<div (click)="audioPreview(msg)" class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
<ion-icon name="mic-outline" class="file-icon"></ion-icon>
<ion-label>{{"Mensagem de voz"}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && msg.downloadLoader == false && msg.uploadingFile == false && msg.downloadAttachmentsTemp == 0" class="icon-download" src="assets/icon/theme/{{ThemeService.currentTheme}}/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="( msg.downloadLoader == true || msg.uploadingFile == true )" class="icon-download" src="assets/gif/theme/{{ThemeService.currentTheme}}/Blocks-loader.svg" slot="end"></ion-icon>
<ion-icon *ngIf="msg.downloadAttachments == false && msg.downloadAttachmentsTemp >= 1 && msg.downloadLoader == false" src="assets/images/retry-svgrepo-com.svg" class="icon-download font-12"> </ion-icon>
</ion-item>
</div>
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && file.title_link">
<audio [src]="file.title_link|safehtml" preload="metadata" controls controlsList="nodownload noplaybackrate"></audio>
</div>
<div class="file-details-optional add-attachment-bg-color">
<ion-label *ngIf="msg.file">
<span *ngIf="file.description">{{file.description}}</span>
<span *ngIf="file.description && msg.file.type != 'application/webtrix'"></span>
</ion-label>
<ion-label class="float-status-all float-status" *ngIf="msg.u.username==sessionStore.user.UserName">
<span *ngIf="msg.online == true && !msg.manualRetry && msg.viewed == 0" class="enviado pl-10"> Enviado</span>
<!-- <ion-icon *ngIf="msg.messageSend == false && !msg.manualRetry" src="assets/images/clock-regular.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0 && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon> -->
<!-- <ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon> -->
<span class="lido pl-10" *ngIf="msg.viewed.length >= 1" > Lido</span>
<div *ngIf="msg.manualRetry" class="try pl-10" (click)="msg.send()">Tentar</div>
</ion-label>
</div>
</div>
</div>
</div>
{{last ? scrollToBottom() : ''}}
</div>
</div>
</div>
<div *ngIf="msg.file.type == 'application/meeting'" class="info-meeting">
<ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button (click)="goToEvent(msg.file)" class="btn-no-color info-meeting-normal"><ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label></button><br />
<ion-label class="info-meeting-medium"><ion-icon name="calendar-outline"></ion-icon> De {{showDateDuration(msg.file.start_date)}} a {{showDateDuration(msg.file.end_date)}}</ion-label><br />
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</ion-label><br />
</div>
</div>
<div class="dateLabel" *ngIf="(msg.t == 'r' || msg.t == 'ul' || msg.t == 'au' || msg.t == 'ru') && msg.dateLabel">
{{ msg.msg}}
</div>
<div *ngIf="msg.t == 'r'" class="info-text">
<ion-label>Alterou o nome do grupo para "{{msg.msg.split('-').join(' ')}}"</ion-label><br />
{{last ? scrollToBottom() : ''}}
</div>
<div *ngIf="msg.t == 'ul'" class="info-text-leave">
<!-- <div *ngFor="let user of allUsers">
<div *ngIf="msg.msg == user.username">
<ion-label>{{user.name}} saiu do grupo</ion-label><br />
</div>
</div> -->
{{last ? scrollToBottom() : ''}}
</div>
<div *ngIf="msg.t == 'ru'" class="info-text-leave">
<!-- <div *ngFor="let user of allUsers">
<div *ngIf="msg.msg == user.username">
<ion-label>{{user.name}} foi removido do grupo</ion-label><br />
</div>
</div> -->
{{last ? scrollToBottom() : ''}}
</div>
<div *ngIf="msg.t == 'au' && msg.msg != sessionStore.user.UserName">
<div *ngFor="let user of []">
<div *ngIf="msg.msg == user.username" class="info-text-leave">
<ion-label>Adicionou {{user.name}}</ion-label><br />
</div>
</div>
{{last ? scrollToBottom() : ''}}
</div>
<!-- <div *ngIf="msg.file" >
<div *ngIf="msg.file.type == 'application/meeting'" class="info-meeting">
<ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button (click)="goToEvent(msg.file)" class="btn-no-color info-meeting-normal"><ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label></button><br />
<ion-label class="info-meeting-medium"><ion-icon name="calendar-outline"></ion-icon> De {{showDateDuration(msg.file.start_date)}} a {{showDateDuration(msg.file.end_date)}}</ion-label><br />
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</ion-label><br />
</div>
{{last ? scrollToBottom() : ''}}
</div> -->
</div>
</div>
<ion-fab horizontal="end" vertical="bottom" slot="fixed">
<ion-fab-button *ngIf="scrollToBottomBtn" (click)="scrollToBottomClicked()" color="light" size="small">
<ion-icon name="chevron-down"></ion-icon>
</ion-fab-button>
<!-- <ion-fab-list side="start">
<ion-fab-button color="light">
<ion-icon name="chevron-down"></ion-icon>
</ion-fab-button>
<ion-fab-button color="light">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button color="light">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
</ion-fab-list> -->
</ion-fab>
</ion-content>
<ion-footer>
<!-- <div class="typing" >
<ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "ChatSystemService.getGroupRoom(roomId).name"
[width]="30"
[circular]="true"
fontFamily="Roboto"></ngx-letters-avatar>
{{ ChatSystemService.getGroupRoom(roomId).userThatIsTyping }} está a escrever...
</div> -->
<div class="width-100 pl-20 pr-20">
<span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span>
<audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls controlsList="nodownload noplaybackrate"></audio>
</div>
<div class="container width-100 d-flex">
<div>
<ion-fab *ngIf="!recording && !lastAudioRecorded && allowTyping" horizontal="start" vertical="bottom" slot="fixed">
<ion-fab-button color="light" size="small">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<!-- <ion-fab-button *ngIf="p.userPermission([p.permissionList.Agenda.access])" title="Nova Reunião" (click)="bookMeeting()" color="light">
<ion-icon name="calendar"></ion-icon>
</ion-fab-button> -->
<ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light">
<ion-icon name="document"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Anexar Fotografia" (click)="addImage()" color="light">
<ion-icon name="image"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Tirar Fotografia" (click)="takePictureMobile()" color="light">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Documento da Gestão Documental" (click)="addFileWebtrix()" color="light">
<ion-icon src="assets/icon/webtrix.svg"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-delete-recording btn-no-color" (click)="deleteRecording()">
<fa-icon class="icon-size-27" icon="trash"></fa-icon>
</button>
</div>
<div class="width-100">
<div *ngIf="!recording && !lastAudioRecorded" class="type-message">
<ion-textarea autocomplete="on" autocorrect="on" spellcheck="true" (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem" class="message-input" rows="1" ></ion-textarea>
</div>
<div *ngIf="recording" class="d-flex align-items-center justify-content-center">
<button (click)="stopRecording()" class="btn-no-color d-flex align-items-center justify-content-center">
<ion-icon class="icon-size-45" name="stop-circle-outline" color="danger"></ion-icon>
</button>
</div>
</div>
<!-- <div class="btn-send">
<button #recordbtn *ngIf="!ChatSystemService.getGroupRoom(roomId).message && !lastAudioRecorded" (click)="startRecording()" class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/default/icons-chat-record-audio.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-record-audio.svg"></ion-icon>
</button>
<button *ngIf="ChatSystemService.getGroupRoom(roomId).message" class="btn-no-color" (click)="sendMessage()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
</button>
<button *ngIf="!ChatSystemService.getGroupRoom(roomId).message && lastAudioRecorded" class="btn-no-color" (click)="sendAudio(lastAudioRecorded)">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
</button>
</div> -->
</div>
</ion-footer>
@@ -1,350 +0,0 @@
@import '~src/function.scss';
.header-toolbar{
--background:transparent;
--opacity: 1;
.main-header{
width: 100%;
height: 100%;
overflow:auto;
padding: 30px 20px 0px 20px;
color:#000;
//transform: translate3d(0, 1px, 0);
.header-top{
width: 100%;
overflow: auto;
padding: 0 !important;
background: #fff;
.middle{
padding: 0!important;
float: left;
width:calc(100% - 77px);
margin: 2.5px 0 0 5px;
}
.right{
padding: 0!important;
float: right;
font-size: rem(25);
color: #0782c9;
margin: 5px 0 0 0;
}
}
.header-bottom{
width: 98%;
overflow: auto;
.header-bottom-icon{
width: rem(30);
font-size: rem(25);
float: left;
padding: 2px;
}
.header-bottom-contacts{
width: calc(100% - 40px);
font-size: rem(15);
color: #797979;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
float: left;
padding: 5px;
margin: 1px;
.contacts-list{
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
}
}
.title{
font-size: rem(25);
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis !important;
float: left;
}
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
}
}
.btn-delete-recording{
margin-left: 20px !important;
}
ion-content{
.welcome-text{
/* width: 322px; */
//width: em(422px);
background: #ebebeb;
text-align: center;
font-size: rem(13);
color: #797979;
padding: 10px;
margin: 0 auto !important;
line-height: 1.2rem;
border-radius: 8px;
}
.info-text{
/* width: 322px; */
width: em(422px);
background: var(--chat-alert-msg-color);
text-align: center;
font-size: rem(13);
color: #262420;
padding: 10px;
margin: 10px auto;
line-height: 1.2rem;
/* margin: 15px 0px 15px 0px; */
border-radius: 8px;
}
.info-text-leave{
display: flex;
align-items: center;
justify-content: center;
width: fit-content;
padding: 10px;
background: #e0e9ee;
border-radius: 8px;
margin: 10px auto;
color: #797979 !important;
font-size: rem(13) !important;
/* margin: 15px 0px 15px 0px; */
.info-text-leave ion-label{
font-size: rem(13) !important;
line-height: 1.2rem;
}
}
.info-meeting{
/* width: 322px; */
width: em(422px);
background: var(--chat-alert-msg-color);
text-align: center;
font-size: rem(13);
color: #262420;
padding: 10px;
margin: 10px auto;
line-height: 1.2rem;
/* margin: 15px 0px 15px 0px; */
border-radius: 8px;
.info-meeting-small{
font-size: rem(10);
font-style: italic;
}
.info-meeting-medium{
font-size: rem(12);
}
.info-meeting-normal{
font-weight: 700;
}
.info-meeting-normal:hover{
text-decoration: underline;
color: #0782c9;
}
}
.messages{
font-size: rem(13);
font-family: Roboto;
overflow: auto;
//set scroll do bottom
position: absolute;
top: 0;
left: 0;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
height: 100%;
word-wrap: break-word;
-webkit-overflow-scrolling: touch;
.incoming-true, .incoming-false{
padding: 15px 20px;
border-radius: 10px;
}
.incoming-true{
margin: 10px 75px 10px 20px;
background: #ebebeb;
float: left;
}
.container-width-100{
width: 100%;
overflow: auto;
}
}
.incoming-false{
margin: 10px 20px 10px 75px;
background: var(--chat-incoming-msg-color);
float: right;
}
.title{
display: inline;
color: var(--title-text-color);
font-weight: bold;
margin-bottom: 5px;
.time{
color: #797979;
text-align: right;
margin-left: 10px;
float: right;
}
}
.message{
.message-attachments{
.file{
align-items: center;
.file-details{
width: 100%;
.file-title{
color: #000;
text-decoration: underline;
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
.file-title:hover{
color: #0782c9;
}
}
}
}
}
}
ion-footer{
padding-top: 7.5px;
padding-bottom: 7.5px;
.container{
justify-content: center;
justify-content: space-evenly;
align-items: center;
margin: 0 !important;
padding: 0 !important;
}
.chat-icon-options{
display:block !important;
font-size: rem(35);
float: right !important;
margin-top: 5px;
}
.chat-icon-send{
font-size: rem(45);
margin: 0 auto;
margin-top: 4px;
}
.type-message{
display: flex;
border: 1px solid #ebebeb;
border-radius: 25px;
padding-left: 15px;
margin: 0 15px 0 75px;
align-items: center;
overflow: auto;
ion-textarea{
margin: 0 !important;
align-self: center;
}
}
.btn-send{
padding-right: 20px !important;
overflow: hidden;
}
}
.typing {
position: relative;
top: -25px;
height: 0px;
left: 0px;
margin-left: 22px;
display: flex;
font-size: rem(12);
align-items: center;
}
.typing ngx-letters-avatar {
padding-right: 5px;
}
.float-status{
position: relative !important;
float: right;
display: flex;
align-items: self-end;
}
.float-status-image{
position: relative !important;
float: right;
display: flex;
align-items: self-end;
top: -15px;
}
.float-status-webtrix {
position: relative !important;
top: 0px !important;
float: right;
display: flex;
align-items: self-end;
}
.float-status-all {
font-size: 10pt !important;
}
.try {
color: red;
background: #f3414159;
padding: 6px;
border-radius: 10px;
cursor: pointer;
}
.dateLabel {
background: #ebebeb !important;
float: unset !important;
margin: 0px auto !important;
width: 111px !important;
text-align: center;
margin-top: 10px !important;
padding: 15px 20px;
border-radius: 10px;
}
.lido,
.enviado {
font-size: rem(11);
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { GroupMessagesPage } from './group-messages.page';
describe('GroupMessagesPage', () => {
let component: GroupMessagesPage;
let fixture: ComponentFixture<GroupMessagesPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GroupMessagesPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(GroupMessagesPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
File diff suppressed because it is too large Load Diff
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ContactsPage } from './contacts.page';
const routes: Routes = [
{
path: '',
component: ContactsPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ContactsPageRoutingModule {}
@@ -1,25 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ContactsPageRoutingModule } from './contacts-routing.module';
import { ContactsPage } from './contacts.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { FilterPipe } from 'src/app/pipes/filter.pipe';
import { PipesModule } from 'src/app/pipes/pipes.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ContactsPageRoutingModule,
PipesModule,
],
exports: [ContactsPage],
declarations: [ContactsPage]
})
export class ContactsPageModule {}
@@ -1,49 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="back-icon cursor-pointer" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/doneIt/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
</div>
<div class="div-title">
<!-- Desktop -->
<ion-label class="title">Nova Conversa</ion-label>
</div>
</div>
</div>
</ion-toolbar>
<ion-toolbar class="toolbar-search">
<div class="search">
<ion-searchbar search-icon="undefined" debounce="500" (ionChange)="onChange($event)" placeholder="Pesquisar por contacto" ></ion-searchbar>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<!-- <ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar> -->
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content">
<ion-progress-bar class="position-absolute" type="indeterminate" *ngIf="loading"></ion-progress-bar>
<ion-virtual-scroll [items]="userList" approxItemHeight="70px" [headerFn]="separateLetter">
<div class="item-divider" *virtualHeader="let header">
<ion-label>{{ header }}</ion-label>
</div>
<div (click)="openMessagesPage(user.wxFullName, user.wxUserId)" *virtualItem="let user" class="item-user cursor-pointer">
<p>{{ user.wxFullName }}</p>
<span class="icon">
<ion-icon [class]="user.status" slot="end" name="ellipse"></ion-icon>
</span>
</div>
</ion-virtual-scroll>
</div>
</ion-content>
@@ -1,136 +0,0 @@
@import '~src/function.scss';
.header-toolbar{
--background:transparent;
--opacity: 1;
.main-header{
width: 100%;
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
.title-content{
margin: 0px auto;
overflow: auto;
padding: 0 !important;
}
.back-icon{
width: 37px;
float: left;
font-size: rem(35);
overflow: auto;
}
.div-title{
width: 221px;
padding: 0!important;
float: left;
margin: 2.5px 0 0 5px;
}
.title{
font-size: rem(25);
}
}
}
.toolbar-search{
--padding-top:0 !important;
--padding-bottom:0 !important;
--padding-start:0 !important;
--padding-end:0 !important;
.search{
border: 1px solid #ebebeb;
margin: 5px 20px 5px 20px;
border-radius: 5px;
height: auto;
padding: 0 !important;
}
.search ion-searchbar{
/* border: 1px solid green; */
width: 100%;
margin: 0 !important;
padding: 0 !important;
--border-radius: 5px;
--box-shadow: none;
overflow: hidden;
--icon-color:var( --font-awesome);
}
}
ion-content{
--background:transparent;
}
.main-content{
width: 100%;
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
padding: 0 0 0 0;
overflow:auto;
.item-divider{
background: #ebebeb;
font-size: rem(15);
margin: 10px 0 10px 0;
padding:5px 0 5px 20px;
}
.item-user{
display: flex;
margin: 10px 20px 10px 20px !important;
overflow: auto;
align-items: center;
}
.item-user p{
display: block;
margin: 0 !important;
width: 90%;
font-size: rem(15);
color: var(--title-text-color);
float: left;
}
.item-user .icon{
width: 10%;
font-size: rem(10);
display: block;
text-align: right;
overflow: auto;
}
.online{
color:#99e47b;
}
.offline{
color:#cbced1;
}
.away{
color:#ffd21f;
}
.invisible{
color:#cbced1;
}
.busy{
color:#f5455c;
}
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ContactsPage } from './contacts.page';
describe('ContactsPage', () => {
let component: ContactsPage;
let fixture: ComponentFixture<ContactsPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactsPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ContactsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,201 +0,0 @@
import { HttpHeaders } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { MessagesPage } from '../messages.page';
import { ThemeService } from 'src/app/services/theme.service'
// import { ChatSystemService } from 'src/app/services/chat/chat-system.service'
import { SessionStore } from 'src/app/store/session.service';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service'
import { HttpErrorResponse } from '@angular/common/http';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { ToastService } from 'src/app/services/toast.service';
class UserToSelect {
}
@Component({
selector: 'app-contacts',
templateUrl: './contacts.page.html',
styleUrls: ['./contacts.page.scss'],
})
export class ContactsPage implements OnInit {
loggedUser: any;
headers: HttpHeaders;
options: any;
textSearch: string;
room: any;
dm: any;
sessionStore = SessionStore
loading = false
@Input() roomId: string;
@Output() openMessage: EventEmitter<any> = new EventEmitter<any>();
@Output() emptyTextDescriptionOpen: EventEmitter<any> = new EventEmitter<any>();
@Output() backToChat: EventEmitter<any> = new EventEmitter<any>();
@Output() closeAllDesktopComponents: EventEmitter<any> = new EventEmitter<any>();
userList: UserContacts[];
originalUserList: any[] = [];
CoolList = []
constructor(
private modalController: ModalController,
public ThemeService: ThemeService,
// public ChatSystemService: ChatSystemService,
private contactsRepositoryService: ContactRepositoryService,
private roomRepositoryService: RoomRepositoryService,
private httpErrorHandle: HttpErrorHandle,
private toastService: ToastService,
) {
this.loggedUser = SessionStore.user.ChatData['data'];
this.textSearch = "";
this.dm = null;
this.room = null;
}
async ngOnInit() {
this.loadUsers();
}
onChange(event) {
this.textSearch = event.detail.value.toLowerCase();
this.userList = this.originalUserList.filter((e) => {
const username = e.wxFullName.toLowerCase();
return username.includes(this.textSearch);
});
this.userList.sort((a, b) => a.wxFullName.toLowerCase().localeCompare(b.wxFullName.toLowerCase()));
}
openMessagesPage(username: string, wxUserId: number) {
this.createRoom(username, wxUserId);
/* if (window.innerWidth < 701) {
this.createRoom(username);
}
else {
let body = {
username: username,
}
this.loading = true
this.chatService.createRoom(body).subscribe(res => {
this.room = res['room'];
this.ChatSystemService.getAllRooms(() => {
this.openMessage.emit(this.room._id);
this.loading = false
}, this.room._id);
}, () => {
this.loading = false
});
}*/
}
async loadUsers() {
try {
let users = await this.contactsRepositoryService.getUsers();
if (users.isOk()) {
const userData = users.value.data.result;
console.log(userData)
this.originalUserList = userData;
this.userList = [...this.originalUserList];
this.userList.sort((a, b) => a.wxFullName.toLowerCase().localeCompare(b.wxFullName.toLowerCase()));
console.log('User data loaded successfully:', this.originalUserList);
} else {
console.error('Failed to fetch users:', users.error);
}
this.loading = false;
} catch (error) {
console.error('Error loading users', error);
this.loading = false;
}
}
separateLetter(record, recordIndex, records) {
const normalize = (str) => str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
if (recordIndex == 0) {
return normalize(record.wxFullName[0]).toUpperCase();
}
let firstPrev = normalize(records[recordIndex - 1].wxFullName[0]).toUpperCase();
let firstCurrent = normalize(record.wxFullName[0]).toUpperCase();
if (firstPrev !== firstCurrent) {
return firstCurrent;
}
return null;
}
doRefresh(event) {
}
close() {
if (this.roomId) {
this.backToChat.emit({ roomId: this.roomId });
} else {
this.closeAllDesktopComponents.emit();
}
}
clicked() {
}
async createRoom(username: string, wxUserId: number) {
const result = await this.roomRepositoryService.create({
roomName: username,
createdBy: SessionStore.user.UserId,
roomType: 0,
expirationDate: null,
members: [wxUserId]
})
console.log(result)
if(result.isOk()) {
this.openMessage.emit(result.value.data.id);
} else if(result.error instanceof HttpErrorResponse) {
this.httpErrorHandle.httpStatusHandle(result.error)
} else {
this.toastService._badRequest("Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.")
console.log(result.error)
}
/* this.chatService.createRoom(body).subscribe(res => {
this.room = res['room'];
this.openMessagesModal(this.room._id);
this.ChatSystemService.getAllRooms()
}); */
}
async openMessagesModal(roomId: any) {
const modal = await this.modalController.create({
component: MessagesPage,
cssClass: 'modal modal-desktop isMessagesChatOpened',
componentProps: {
roomId: roomId,
},
});
modal.onDidDismiss();
await modal.present();
}
}
@@ -1,21 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MessagesPage } from './messages.page';
const routes: Routes = [
{
path: '',
component: MessagesPage
},
{
path: 'contacts',
loadChildren: () => import('./contacts/contacts.module').then( m => m.ContactsPageModule)
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
@@ -1,33 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { MessagesPageRoutingModule } from './messages-routing.module';
import { MessagesPage } from './messages.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { MatButtonModule } from '@angular/material/button';
import {MatMenuModule} from '@angular/material/menu';
import { LettersAvatarModule } from "ngx-letters-avatar";
import { PipesModule } from 'src/app/pipes/pipes.module';
import { SafehtmlPipe } from 'src/app/pipes/safehtml.pipe';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
FontAwesomeModule,
MessagesPageRoutingModule,
MatButtonModule,
MatMenuModule,
LettersAvatarModule,
PipesModule,
],
exports: [MessagesPage],
declarations: [MessagesPage]
})
export class MessagesPageModule {}
@@ -1,223 +0,0 @@
<ion-header class="ion-no-border" >
<ion-toolbar class="header-toolbar" >
<div class="main-header" *ngIf="roomData$ | async as roomData">
<div class="header-top">
<div class="middle" >
<ion-label class="title"> {{ roomData.roomName }}</ion-label>
<!-- <button (click)="ChatMessageDebuggingPage()">Dev</button> -->
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus" class="online" name="ellipse"></ion-icon></span>
</div>
<div class="right">
<button title="Menu" class="btn-no-color" (click)="_openMessagesOptions()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg">
</ion-icon>
</button>
</div>
</div>
<div class="d-flex header-bottom" >
<div class="header-bottom-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
</div>
<ion-list class="header-bottom-contacts" *ngIf="roomMembers$ | async as memberList">
<ng-container *ngFor="let user of memberList; let i = index">
{{ user.wxFullName }}<ng-container *ngIf="i < memberList.length - 1">, </ng-container>
</ng-container>
</ion-list>
</div>
</div>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
</ion-toolbar>
</ion-header>
<ion-content >
<div class="messages height-100 width-100 d-flex flex-column" #scrollMe >
<div
*ngFor="let message of messages1[roomId]" class="messages-list-item-wrapper"
[ngClass]="{'my-message': message.sender.wxUserId === sessionStore.user.UserId, 'other-message': message.sender.wxUserId !== sessionStore.user.UserId}"
>
<div class="message-container">
<div class="d-flex justify-content-between">
<div>
<div>
{{ message.message }}
</div>
<div *ngFor="let attachment of message.attachments; let i = index">
<div *ngIf="attachment.source == MessageAttachmentFileSource.Webtrix">
<ion-icon src="assets/icon/webtrix.svg" class="file-icon font-25"></ion-icon>
<ion-label>{{ attachment.fileName}}</ion-label>
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'default' && attachment.type != 'webtrix' && !( msg.downloadLoader == true || msg.uploadingFile == true ) " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && attachment.type != 'webtrix' && !( msg.downloadLoader == true || msg.uploadingFile == true ) " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="( msg.downloadLoader == true || msg.uploadingFile == true )" class="icon-download" src="assets/gif/theme/{{ThemeService.currentTheme}}/Blocks-loader.svg" slot="end"></ion-icon> -->
</div>
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Image">
<img [src]="attachment.safeFile">
</div>
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Audio">
<audio [src]="attachment.safeFile|safehtml" preload="metadata" class="flex-grow-1" controls controlsList="nodownload noplaybackrate"></audio>
</div>
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Doc">
<fa-icon *ngIf="attachment.mimeType == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
<fa-icon *ngIf="attachment.mimeType == 'application/word'" icon="file-word" class="word-icon">
</fa-icon>
<fa-icon *ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'" icon="file-word" class="word-icon"></fa-icon>
<fa-icon
*ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"
icon="file-word" class="excel-icon"></fa-icon>
<ion-icon *ngIf="attachment.mimeType == 'application/webtrix'" src="assets/icon/webtrix.svg">
</ion-icon>
<ion-icon *ngIf="attachment.mimeType == 'application/meeting'" src="assets/icon/webtrix.svg">
</ion-icon>
<ion-label>{{ attachment.fileName}}</ion-label>
</div>
</div>
</div>
<div>
<div class="message-item-options d-flex justify-content-end">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="messageDelete(message)" class="menuButton">Apagar mensagem</button>
<button (click)="editMessage(message)" class="menuButton">Editar mensagem</button>
<button (click)="toggleEmojiPicker(message)" class="menuButton">Reagir mensagem</button>
</mat-menu>
</div>
</div>
</div>
<div style="text-align: end;">
<div *ngIf="message.messageStatus != 'send'" style="font-size: .6875rem;">A enviar</div>
<div *ngIf="message.messageStatus == 'send'" style="font-size: .6875rem;">Enviado</div>
</div>
<!-- Emoji Picker -->
<div *ngIf="selectedMessage === message" class="emoji-picker" [ngStyle]="{'bottom': '0', 'right': '0'}">
<span *ngFor="let emoji of emojis" (click)="addReaction(message, emoji)" class="emoji-icon">
{{ emoji }}
</span>
</div>
</div>
<!-- current emoji -->
<div>
<span *ngFor="let reaction of message.reactions" class="emoji-icon">
{{ reaction.reaction }}
</span>
</div>
</div>
</div>
<ion-fab horizontal="start" vertical="bottom" slot="fixed">
<div #array>
</div>
</ion-fab>
</ion-content>
<!-- <ion-footer (click)="ChatSystemService.getDmRoom(roomId).sendReadMessage()"> -->
<ion-footer >
<!-- <div class="typing" *ngIf="ChatSystemService.getDmRoom(roomId).otherUserType == true" >
<ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "ChatSystemService.getDmRoom(roomId).name"
[width]="30"
[circular]="true"
fontFamily="Roboto"></ngx-letters-avatar>
está a escrever...
</div> -->
<div class="width-100 pl-20 pr-20">
<span >{{durationDisplay}}</span>
<div class=" audioDiv d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded">
<div (click)="start(audioRecordedSafe)" *ngIf="!isPlaying" > <ion-icon slot="icon-only" name="play"></ion-icon> </div>
<div (click)="togglePlayer(isPlaying)" *ngIf="isPlaying"> <ion-icon slot="icon-only" name="pause"></ion-icon> </div>
<ion-range #range [(ngModel)]="audioProgress" max="100" (mouseup)="seek()"></ion-range>
</div>
</div>
<div class="container width-100 d-flex">
<div>
<ion-fab *ngIf="!recording && !lastAudioRecorded && allowTyping" horizontal="start" vertical="bottom" slot="fixed">
<ion-fab-button color="light" size="small">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<!-- <ion-fab-button *ngIf="p.userPermission([p.permissionList.Agenda.access])" title="Nova Reunião" (click)="bookMeeting()" color="light">
<ion-icon name="calendar"></ion-icon>
</ion-fab-button> -->
<ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light">
<ion-icon name="document"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Anexar Fotografia" (click)="pickPicture()" color="light">
<ion-icon name="image"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Tirar Fotografia" (click)="takePictureMobile()" color="light">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
<ion-fab-button title="Documento da Gestão Documental" (click)="addFileWebtrix()" color="light">
<ion-icon src="assets/icon/webtrix.svg"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-no-color" (click)="deleteRecording()">
<fa-icon class="icon-size-27" icon="trash"></fa-icon>
</button>
</div>
<div class="width-100">
<div *ngIf="!recording && !lastAudioRecorded" class="type-message">
<ion-textarea *ngIf="allowTyping" (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem" class="message-input" rows="1" [(ngModel)]="textField" (ionChange)="sendTyping()" (click)="sendReadAt()"></ion-textarea>
</div>
<div *ngIf="recording" class="d-flex align-items-center justify-content-center">
<button (click)="stopRecording()" class="btn-no-color d-flex align-items-center justify-content-center">
<ion-icon class="icon-size-45" name="stop-circle-outline" color="danger"></ion-icon>
</button>
</div>
</div>
<div class="btn-send">
<button #recordbtn *ngIf="textField == '' && !lastAudioRecorded" (click)="startRecording()" class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/default/icons-chat-record-audio.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-record-audio.svg"></ion-icon>
</button>
<button *ngIf="textField != ''" class="btn-no-color" (click)="sendMessage()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
</button>
<button *ngIf="textField == '' && lastAudioRecorded" class="btn-no-color" (click)="sendAudio(lastAudioRecorded)">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
</button>
</div>
</div>
</ion-footer>
@@ -1,466 +0,0 @@
@import "~src/function.scss";
.header-toolbar {
--background: transparent;
--opacity: 1;
.main-header {
width: 100%;
/* 400px */
height: 100%;
font-family: Roboto;
background-color: #fff;
overflow: hidden;
//padding: 0px 20px 0px 20px;
color: #000;
transform: translate3d(0, 1px, 0);
padding: 30px 20px 0 20px !important;
.header-top {
width: 100%;
overflow: auto;
//padding: 0 !important;
background: #fff;
.middle {
//padding: 0!important;
float: left;
width: calc(100% - 77px);
margin: 2px 0 0 5px;
display: flex;
align-items: center;
}
.right {
padding: 0 !important;
float: right;
font-size: rem(25);
color: #0782c9;
margin: 5px 0 0 0;
}
}
.header-bottom {
width: 95%;
overflow: auto;
.header-bottom-icon {
width: rem(30);
font-size: rem(25);
padding: 2px;
}
.header-bottom-contacts {
font-size: rem(15);
color: #797979;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 5px;
margin: 1px;
}
}
.title {
font-size: rem(25);
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis !important;
float: left;
}
.div-icon {
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon {
float: right;
padding-left: 20px;
}
}
}
ion-content {
width: 100%;
height: 100%;
padding: 30px 20px 0 20px !important;
.welcome-text {
/* width: 322px; */
/* width: em(422px); */
width: 100%;
background: #ebebeb;
text-align: center;
font-size: rem(13);
color: #797979;
padding: 10px;
margin: 0 auto !important;
line-height: 1.2rem;
//margin: 20px 39px 25px;
border-radius: 8px;
border: 1px solid red;
}
.info-meeting {
/* width: 322px; */
width: em(422px);
background: var(--chat-alert-msg-color);
text-align: center;
font-size: rem(13);
color: #262420;
padding: 10px;
margin: 10px auto;
line-height: 1.2rem;
/* margin: 15px 0px 15px 0px; */
border-radius: 8px;
.info-meeting-small {
font-size: rem(10);
font-style: italic;
}
.info-meeting-medium {
font-size: rem(12);
}
.info-meeting-normal {
font-weight: 700;
}
.info-meeting-normal:hover {
text-decoration: underline;
color: #0782c9;
}
}
.messages {
font-size: rem(13);
font-family: Roboto;
overflow: auto;
//set scroll do bottom
// position: absolute;
// top: 0;
// left: 0;
// overflow-x: hidden;
// overflow-y: auto;
// width: 100%;
// height: 100%;
// word-wrap: break-word;
// -webkit-overflow-scrolling: touch;
.other-message,
.my-message {
.message-container {
padding: 15px 20px;
margin: 10px 20px 10px 75px;
background: var(--chat-incoming-msg-color);
border-radius: 10px;
}
}
.other-message {
display: flex;
/* justify-content: flex-end; */
align-items: start;
flex-direction: column;
// float: left;
// Styles for incoming messages from other users
justify-content: flex-start;
.message-container {
padding: 15px 20px;
margin: 10px 75px 10px 20px;
background: #ebebeb;
border-radius: 10px;
}
}
}
.my-message {
display: flex;
/* justify-content: flex-end; */
align-items: end;
flex-direction: column;
}
.message-bubble {
// Styles for the message bubble
background-color: #e2e2e2; // Example background color
padding: 10px; // Adjust as needed
border-radius: 10px; // Adjust as needed
}
.title {
display: inline;
color: var(--title-text-color);
font-weight: bold;
margin-bottom: 5px;
.time {
color: #797979;
text-align: right;
margin-left: 10px;
float: right;
}
}
.message {
.message-attachments {
.file {
align-items: center;
.file-details {
width: 100%;
.file-title {
color: #000;
text-decoration: underline;
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
.file-title:hover {
color: #0782c9;
}
}
}
}
}
}
ion-footer {
padding-top: 7.5px;
padding-bottom: 7.5px;
.container {
justify-content: center;
justify-content: space-evenly;
align-items: center;
}
.chat-icon-options {
display: block !important;
font-size: rem(35);
float: right !important;
margin-top: 5px;
}
.chat-icon-send {
font-size: rem(45);
margin: 0 auto;
margin-top: 4px;
}
.chat-icon-download {
font-size: 95px;
margin: 0 auto;
margin-top: 4px;
border: 1px solid red;
}
.type-message {
display: flex;
border: 1px solid #ebebeb;
border-radius: 25px;
padding-left: 15px;
margin: 0 15px 0 60px;
align-items: center;
overflow: auto;
ion-textarea {
margin: 0 !important;
align-self: center;
}
}
}
.text-color-blue {
font-size: rem(15);
color: #0782c9;
font-weight: 500;
letter-spacing: normal;
}
.user-status-online {
display: block;
float: left;
color: #99e47b;
padding-left: 10px;
}
.online {
display: block;
float: left;
color: #99e47b;
padding-left: 10px;
}
.offline {
color: #cbced1;
display: block;
float: left;
padding-left: 10px;
}
.away {
color: #ffd21f;
display: block;
float: left;
padding-left: 10px;
}
.invisible {
color: #cbced1;
display: block;
float: left;
padding-left: 10px;
}
.busy {
color: #f5455c;
display: block;
float: left;
padding-left: 10px;
}
.float-status {
position: relative !important;
float: right;
display: flex;
align-items: self-end;
}
.float-status-image {
position: relative !important;
float: right;
display: flex;
align-items: self-end;
top: -15px;
}
.float-status-webtrix {
position: relative !important;
top: 0px !important;
float: right;
display: flex;
align-items: self-end;
}
.float-status-all {
font-size: 10pt !important;
}
.typing {
position: relative;
top: -25px;
height: 0px;
left: 0px;
margin-left: 22px;
display: flex;
font-size: rem(12);
align-items: center;
}
.typing ngx-letters-avatar {
padding-right: 5px;
}
.div-do-audio {
border: 1px solid red !important;
overflow: auto;
}
.message-box {
flex: auto;
margin-right: 9px;
}
.divColor {
color: #000;
width: 10ch;
height: 10ch;
}
.audioDiv {
border-radius: 25px;
background: #cbced1;
padding: 20px;
height: 50px;
}
.audioButtonPlay {
margin-bottom: 100%;
right: 50%;
}
.try {
color: red;
background: #f3414159;
padding: 6px;
border-radius: 10px;
cursor: pointer;
}
.red-top {
border-top: 1px solid red !important;
}
.red {
color: red !important;
}
.lido,
.enviado {
font-size: rem(11);
}
.dateLabel {
background: #ebebeb !important;
float: unset !important;
margin: 0px auto !important;
width: 111px !important;
text-align: center;
}
.message-item-options {
//display: none !important; /* Hide the options by default */
opacity: 0 !important;
}
.message-container:hover .message-item-options {
//display: block !important; /* Show the options on hover */
opacity: 1 !important;
}
.message-item-options {
position: relative;
}
.emoji-picker {
display: flex;
flex-wrap: wrap;
background: white;
border: 1px solid #ccc;
padding: 5px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
}
.emoji-icon {
font-size: 20px;
cursor: pointer;
margin: 2px;
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { MessagesPage } from './messages.page';
describe('MessagesPage', () => {
let component: MessagesPage;
let fixture: ComponentFixture<MessagesPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MessagesPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(MessagesPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
File diff suppressed because it is too large Load Diff
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ContactsPage } from './contacts.page';
const routes: Routes = [
{
path: '',
component: ContactsPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ContactsPageRoutingModule {}
@@ -1,23 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ContactsPageRoutingModule } from './contacts-routing.module';
import { ContactsPage } from './contacts.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { BtnSeguintePageModule } from 'src/app/shared/btn-seguinte/btn-seguinte.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ContactsPageRoutingModule,
BtnSeguintePageModule,
],
declarations: [ContactsPage]
})
export class ContactsPageModule {}
@@ -1,56 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="back-icon cursor-pointer">
<button class="btn-no-color" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="div-title">
<ion-label class="title">Contactos</ion-label>
</div>
<app-btn-seguinte (click)="groupMessages()" class="cursor-pointer"></app-btn-seguinte>
</div>
</div>
</ion-toolbar>
<ion-toolbar class="toolbar-search">
<div class="search">
<ion-searchbar search-icon="undefined" (ionChange)="onChange($event)" placeholder="Pesquisar por contacto" ></ion-searchbar>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<!-- <ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar> -->
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content">
<!-- <ion-list>
<ion-item *ngFor="let user of searchedItem">
{{user.name}}
</ion-item>
</ion-list> -->
<!-- <ion-virtual-scroll [items]="ChatSystemService.users" approxItemHeight="70px" [headerFn]="separateLetter">
<div class="item-divider" *virtualHeader="let header">
<ion-label>{{header}}</ion-label>
</div>
<div *virtualItem="let user" class="item-checkbox">
<ion-checkbox color="primary"></ion-checkbox>
<p>{{user.first}} {{user.last}}</p>
<ion-icon name="ellipse"></ion-icon>
</div>
</ion-virtual-scroll> -->
</div>
</ion-content>
@@ -1,127 +0,0 @@
@import '~src/function.scss';
.header-toolbar{
--background:transparent;
--opacity: 1;
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
.title-content{
margin: 0px auto;
overflow: auto;
padding: 0 !important;
}
.back-icon{
width: 37px;
float: left;
font-size: rem(35);
overflow: auto;
}
.div-title{
width: 221px;
padding: 0!important;
float: left;
margin: 2.5px 0 0 5px;
}
.title{
font-size: rem(25);
}
}
}
.toolbar-search{
--padding-top:0 !important;
--padding-bottom:0 !important;
--padding-start:0 !important;
--padding-end:0 !important;
.search{
border: 1px solid #ebebeb;
margin: 5px 20px 5px 20px;
border-radius: 5px;
}
.search ion-searchbar{
/* border: 1px solid green; */
width: 100%;
margin: 0 !important;
padding: 0 !important;
--border-radius: 5px;
--box-shadow: none;
overflow: auto;
--icon-color:#0d89d1;
}
}
ion-content{
--background:transparent;
}
.main-content{
width: 100%;
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 0 0 0 0;
.item-divider{
background: #ebebeb;
font-size: rem(15);
margin: 10px 0 10px 0;
padding:5px 0 5px 20px;
}
.item-checkbox{
display: flex;
margin: 10px 20px 10px 20px !important;
overflow: auto;
align-items: center;
}
.item-checkbox ion-checkbox{
--border-color: #0d89d1;
--background-checked:#0d89d1;
float: left;
}
.item-checkbox p{
display: block;
margin: 0 !important;
width: 330px;
padding-left: 10px;
font-size: rem(15);
color: #0d89d1;
float: left;
}
.item-checkbox ion-icon{
font-size: rem(10);
float: left;
color:#99e47b;
margin-left: 10px;
}
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ContactsPage } from './contacts.page';
describe('ContactsPage', () => {
let component: ContactsPage;
let fixture: ComponentFixture<ContactsPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactsPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ContactsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,73 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { GroupMessagesPage } from '../../group-messages/group-messages.page';
import { ThemeService } from 'src/app/services/theme.service'
// import { ChatSystemService } from 'src/app/services/chat/chat-system.service'
@Component({
selector: 'app-contacts',
templateUrl: './contacts.page.html',
styleUrls: ['./contacts.page.scss'],
})
export class ContactsPage implements OnInit {
options:any;
constructor(
private modalController: ModalController,
public ThemeService: ThemeService,
// public ChatSystemService: ChatSystemService
)
{
}
ngOnInit() {
this.loadUsers();
}
loadUsers(){
// sthis.ChatSystemService.getUser()
}
separateLetter(record, recordIndex, records){
if(recordIndex == 0){
return record.first[0];
}
let first_prev = records[recordIndex - 1].first[0];
let first_current = record.first[0];
if(first_prev != first_current){
return first_current;
}
return null;
}
doRefresh(event){
}
close(){
this.modalController.dismiss();
}
onChange(event){
}
clicked(){
}
async groupMessages(){
const modal = await this.modalController.create({
component: GroupMessagesPage,
componentProps: {},
cssClass: 'contacts',
backdropDismiss: false
});
modal.onDidDismiss();
await modal.present();
}
}
@@ -1,21 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NewGroupPage } from './new-group.page';
const routes: Routes = [
{
path: '',
component: NewGroupPage
},
{
path: 'contacts',
loadChildren: () => import('./contacts/contacts.module').then( m => m.ContactsPageModule)
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class NewGroupPageRoutingModule {}
@@ -1,22 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { NewGroupPageRoutingModule } from './new-group-routing.module';
import { NewGroupPage } from './new-group.page';
import { SharedModule } from 'src/app/shared/shared.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
NewGroupPageRoutingModule
],
exports: [NewGroupPage],
declarations: [NewGroupPage]
})
export class NewGroupPageModule {}
@@ -1,46 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="left">
<button class="btn-no-color" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="middle">
<ion-label class="title">Novo Grupo</ion-label>
</div>
<div *ngIf="groupName">
<button class="btn-no-color btn-criar" (click)="createGroup()">
<ion-label>Criar grupo</ion-label>
</button>
</div>
</div>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="main-content width-100">
<div class="item-container">
<ion-input [(ngModel)]="groupName" placeholder="Título"></ion-input>
</div>
<div class="item-container-no-border">
<ion-checkbox (ionChange)="onDateExpirationChange($event)" color="primary"></ion-checkbox>
<ion-label>Grupo Ultra-secreto</ion-label>
</div>
<div *ngIf="showDuration" class="container-div">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-duration.svg"></ion-icon>
</div>
<div class="ion-input-class">
<ion-input (click)="showPicker()" [(ngModel)]="displayDuration" placeholder="Duração"></ion-input>
</div>
</div>
</div>
</div>
</ion-content>
@@ -1,162 +0,0 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.div-top-header{
width: 400px;
margin: 0 auto;
background-color: #0782c9;
overflow: auto;
padding-top: 15px;
border: 0!important;
.div-search{
font-size: rem(45);
float: left;
margin: 0 0 0 10px
}
.div-logo{
background: transparent;
width: 140px;
margin: 5px 0 0px 71px;
float: left;
}
.div-logo img{
width: 100%;
}
.div-profile{
font-size: rem(45);
float: right;
margin-right: 10px;
}
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
//width: 360px;
margin: 0px auto;
overflow: auto;
padding: 0 !important;
background: #fff;
.left{
width: 37px;
float: left;
font-size: rem(35);
overflow: auto;
}
.middle{
padding: 0!important;
float: left;
width: 221px;
//margin: 2.5px 0 0 5px;
}
.btn-criar{
padding: 0!important;
float: right;
font-size: rem(15);
color: var(--font-awesome);
margin: 8px 5px 0 5px;
}
.right{
padding: 0!important;
float: right;
font-size: rem(15);
color: #0782c9;
margin: 8px 0 0 5px;
}
}
.title{
font-size: rem(25);
}
.div-icon{
width: rem(40);
float: right;
font-size: rem(35);
overflow: auto;
padding: 1px;
}
.div-icon ion-icon{
float: right;
padding-left: 20px;
}
}
.main-content{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 15px 20px 0 20px;
.item-container{
//width: 360px;
margin: 15px auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.item-container-no-border{
display: flex;
//width: 360px;
margin: 25px auto;
border-radius: 5px;
align-items: center;
}
.item-container-no-border ion-label{
padding-left: 10px;
font-size: rem(12);
color: #000;
}
}
.container-div{
width: 100%;
margin-bottom: 15px;
overflow: auto;
.ion-item-class-2{
width: 100%;
margin: 0px auto;
.ion-icon-class{
width: 5%;
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
}
.ion-input-class{
width: 93%;
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
margin-left: 2%;
float: left;
}
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { NewGroupPage } from './new-group.page';
describe('NewGroupPage', () => {
let component: NewGroupPage;
let fixture: ComponentFixture<NewGroupPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NewGroupPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(NewGroupPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,319 +0,0 @@
import { Component, EventEmitter, Input, OnInit, Output,ViewContainerRef } from '@angular/core';
import { PickerController, PopoverController } from '@ionic/angular';
// import { ChatSystemService } from 'src/app/services/chat/chat-system.service';
import { DataService } from 'src/app/services/data.service';
import { GroupDurationPage } from 'src/app/shared/popover/group-duration/group-duration.page';
import { SessionStore } from 'src/app/store/session.service';
import { ThemeService } from 'src/app/services/theme.service';
import { RouteService } from 'src/app/services/route.service';
import { HttpErrorResponse } from '@angular/common/http';
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'
@Component({
selector: 'app-new-group',
templateUrl: './new-group.page.html',
styleUrls: ['./new-group.page.scss'],
})
export class NewGroupPage implements OnInit{
isGroupCreated:boolean;
showLoader: boolean;
displayDuration: any;
showDuration: boolean;
expirationDate:Date = null;
_day:any;
selectedDuration = ['','',''];
countDownTime:any;
task:any;
event: any
link = ''
documents: any;
loggedUserChat: any;
contact: {
Email: string
DisplayName: string
}[]
@Input() roomId: string;
@Input() groupName:string;
@Output() addGroupMessage:EventEmitter<any> = new EventEmitter<any>();
@Output() closeAllDesktopComponents:EventEmitter<any> = new EventEmitter<any>();
@Output() backToChat:EventEmitter<any> = new EventEmitter<any>();
constructor(
private pickerController: PickerController,
private popoverController: PopoverController,
private dataService:DataService,
// public ChatSystemService: ChatSystemService,
public ThemeService: ThemeService,
private RouteService: RouteService,
private viewContainerRef: ViewContainerRef,
private roomRepositoryService: RoomRepositoryService,
private httpErrorHandle: HttpErrorHandle,
)
{
this.loggedUserChat = SessionStore.user.ChatData['data'];
this.isGroupCreated = false;
}
ngOnInit() {
this.task = this.dataService.get("task");
this.event = this.dataService.get("event");
if(this.task && this.dataService.get("newGroup")) {
this.link = this.dataService.get("link");
this.groupName = this.task.Folio;
this.documents = this.dataService.get("documents");
this.dataService.set("newGroup", false);
this.dataService.set("link", false);
} else if (this.event && this.dataService.get("newGroup")) {
//
this.link = this.dataService.get("link");
this.groupName = this.event.Subject;
this.documents = this.dataService.get("documents");
this.contact = this.dataService.get("contacts");
//
this.dataService.set("newGroup", false);
this.dataService.set("link", false);
} else {
this.dataService.clear();
}
}
onDateExpirationChange(event) {
this.showDuration = event.detail.checked;
if(event.detail.checked) {
this.expirationDate = new Date();
}
else {
this.expirationDate = null;
}
}
close() {
if(this.link) {
this.viewContainerRef.clear();
this.RouteService.goBack();
this.dataService.set("link", false);
} else {
if(this.roomId) {
this.backToChat.emit({roomId: this.roomId});
this.viewContainerRef.clear();
} else {
this.viewContainerRef.clear();
this.closeAllDesktopComponents.emit();
}
}
}
async createGroup() {
this.createGroup1()
}
async createGroup1() {
const result = await this.roomRepositoryService.create({
roomName: this.groupName,
createdBy: SessionStore.user.UserId,
roomType: 0,
expirationDate: this.expirationDate?.toISOString(),
members: []
})
if(result.isOk()) {
this.addGroupMessage.emit(result.value.data.id);
} else if(result.error instanceof HttpErrorResponse) {
this.httpErrorHandle.httpStatusHandle(result.error)
}
}
createGroupWithAttachmentsCath(res: any) {
// if(!this.ChatSystemService.getGroupRoom(res.result.rid)) {
// setTimeout(() => {
// this.createGroupWithAttachmentsCath(res)
// }, 1500)
// } else {
// this.createGroupWithAttachments(res)
// }
}
createGroupWithAttachments(res: any) {
// this.ChatSystemService.getGroupRoom(res.result.rid).hasLoadHistory = true;
// if(this.documents) {
// this.documents.forEach(element => {
// this.ChatSystemService.getGroupRoom(res.result.rid).send({
// file: {
// "name": element.Assunto,
// "type": "application/webtrix",
// "ApplicationId": element.ApplicationId,
// "DocId": element.DocId,
// "Assunto": element.Assunto,
// },
// temporaryData: {
// data: {
// selected: {
// Id: element.DocId,
// ApplicationType: element.ApplicationId
// }
// }
// },
// attachments: [{
// "title": element.Assunto,
// "description": element.Assunto,
// "title_link_download": true,
// "type": "webtrix",
// "text": element.Assunto,
// "thumb_url": "https://static.ichimura.ed.jp/uploads/2017/10/pdf-icon.png",
// }],
// })
// });
// }
// this.ChatSystemService.getAllRooms();
// setTimeout(() => {
// this.groupName = ""
// }, 150);
}
async setDuration(ev: any) {
const popover = await this.popoverController.create({
component: GroupDurationPage,
cssClass: 'group-duration',
event: ev,
translucent: true
});
return await popover.present();
}
async showPicker() {
const picker = await this.pickerController.create({
cssClass: '',
buttons: [
{
text: 'Cancelar', role: 'cancel', cssClass: 'btn-cancel'
},
{
text: 'Ok',
cssClass: 'btn-cancel',
handler:(value:any)=>{
let now = new Date();
this.expirationDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + value.days.value, now.getHours() + value.hours.value, now.getMinutes() + value.minutes.value, now.getSeconds(), now.getMilliseconds())
this.selectedDuration = [
value.days.value,
value.hours.value,
value.minutes.value,
]
if(value.days.value != null && value.hours.value != null && value.minutes.value != null){
if(value.days.value > 0){
if(value.days.value == 1){
if(value.hours.value == 1){
this.displayDuration = value.days.value + " day " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
else{
if(value.hours.value == 1){
this.displayDuration = value.days.value + " days " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
}
else{
if(value.hours.value == 1){
this.displayDuration = value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
}
},
},
],
columns: [
{
name: 'days',
prefix: 'Dias',
options: [
{ text: '0', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
{ text: '5', value: 5 },
{ text: '6', value: 6 },
]
},
{
name: 'hours',
prefix: 'Horas',
options: [
{ text: '0', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
{ text: '5', value: 5 },
{ text: '6', value: 6 },
{ text: '7', value: 7 },
{ text: '8', value: 8 },
]
},
{
name: 'minutes',
prefix: 'Minutos',
selectedIndex: 0,
options: [
{ text: '5', value: 5 },
{ text: '10', value: 10 },
{ text: '15', value: 15 },
{ text: '20', value: 20 },
{ text: '25', value: 25 },
{ text: '30', value: 30 },
{ text: '35', value: 35 },
{ text: '45', value: 45 },
{ text: '50', value: 50 },
{ text: '55', value: 55 },
]
}
]
});
await picker.present();
picker.onDidDismiss().then(async data => {
let day = await picker.getColumn('days');
let hour = await picker.getColumn('hours');
let minutes = await picker.getColumn('minutes');
});
}
}
@@ -15,7 +15,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { ExpedienteService } from 'src/app/Rules/expediente.service';
import { PermissionService } from 'src/app/services/permission.service';
import { ThemeService } from 'src/app/services/theme.service'
import { NewGroupPage } from 'src/app/pages/chat/new-group/new-group.page';
import { NewGroupPage } from 'src/app/ui/chat/modal/new-group/new-group.page';
import { RouteService } from 'src/app/services/route.service';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
@@ -10,7 +10,7 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { PedidoService } from 'src/app/Rules/pedido.service';
import { PermissionService } from 'src/app/services/permission.service';
import { NewGroupPage } from 'src/app/pages/chat/new-group/new-group.page';
import { NewGroupPage } from 'src/app/ui/chat/modal/new-group/new-group.page';
import { ForwardPage } from 'src/app/modals/forward/forward.page';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
@@ -50,7 +50,7 @@ export class RequestOptionsPage implements OnInit {
this.activatedRoute.queryParams.subscribe(params => {
if(params["serialNumber"]) {
this.serialNumber = params["serialNumber"];
//
//
}
});
@@ -67,7 +67,7 @@ export class RequestOptionsPage implements OnInit {
}
ngOnInit() {
this.profile = "mdgpr";
window.onresize = (event) => {
@@ -91,7 +91,7 @@ export class RequestOptionsPage implements OnInit {
sendExpedienteToPending() {
const loader = this.toastService.loading()
this.processes.SetTaskToPending(this.task.SerialNumber).subscribe(res=>{
this.httpErrorHandle.httpsSucessMessagge('Enviar para Pendentes')
this.close();
loader.remove()
@@ -187,9 +187,9 @@ export class RequestOptionsPage implements OnInit {
});
modal.onDidDismiss().then(res=> {
if(res['data']=='openDiscart') {
} else {
this.popoverController.dismiss('close')