conflit soved after merge

This commit is contained in:
Eudes Inácio
2022-03-31 16:48:53 +01:00
53 changed files with 978 additions and 618 deletions
+2 -2
View File
@@ -35,7 +35,7 @@ npm-debug.log*
# Custom # Custom
/package-lock.json /package-lock.json
src/app/architect/ src/app/architect/
src/environments/environment.e2e.ts src/environments/environment.e2e.ts
.env .env
@@ -52,4 +52,4 @@ node_modules_
node_modules__ node_modules__
plugins_ plugins_
ios ios
src/plugin/beast-orm src/plugin/beast-orm
+3 -3
View File
@@ -6240,9 +6240,9 @@
} }
}, },
"beast-orm": { "beast-orm": {
"version": "1.0.0", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/beast-orm/-/beast-orm-1.0.0.tgz", "resolved": "https://registry.npmjs.org/beast-orm/-/beast-orm-1.0.3.tgz",
"integrity": "sha512-wSholUbFMteq50U3QM0o4H3xY9IpevpG9MPlq0ZK8yRtRkIuKf/YoZW4QUwFOfY72PJbNzp68z7Ln/iFhpOxDg==" "integrity": "sha512-kSTc8Sosm1CbLjSGc+nA1s9i4QmGQoF1rfWDmhTrHOvH+uZAtRXbZAypzscMmF67g04mK5XAuB+TUoKV5XmNiQ=="
}, },
"big-integer": { "big-integer": {
"version": "1.6.49", "version": "1.6.49",
+1 -1
View File
@@ -100,7 +100,7 @@
"angular-svg-icon": "^12.0.0", "angular-svg-icon": "^12.0.0",
"angular-tag-cloud-module": "^5.2.2", "angular-tag-cloud-module": "^5.2.2",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"beast-orm": "^1.0.0", "beast-orm": "^1.0.3",
"bootstrap": "^4.5.0", "bootstrap": "^4.5.0",
"build": "0.1.4", "build": "0.1.4",
"capacitor-voice-recorder": "^2.0.0", "capacitor-voice-recorder": "^2.0.0",
+1 -1
View File
@@ -6,7 +6,7 @@ import { ProcessesService } from '../services/processes.service';
import { DespachoStore } from '../store/despacho-store.service'; import { DespachoStore } from '../store/despacho-store.service';
import { LoaderService } from 'src/app/store/loader.service' import { LoaderService } from 'src/app/store/loader.service'
import { SessionStore } from '../store/session.service'; import { SessionStore } from '../store/session.service';
import { PermissionService } from '../services/worker/permission.service'; import { PermissionService } from '../services/permission.service';
import { SortService } from '../services/functions/sort.service'; import { SortService } from '../services/functions/sort.service';
@Injectable({ @Injectable({
+5 -5
View File
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ProcessesService } from '../services/processes.service'; import { ProcessesService } from '../services/processes.service';
import { PermissionService } from '../services/worker/permission.service'; import { PermissionService } from '../services/permission.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -22,10 +22,10 @@ export class PedidoService {
createDeferimento(body: any) { createDeferimento(body: any) {
if(this.p.userRole(['PR'])) { if(this.p.userRole(['PR'])) {
throw('PR cant create Deferimento') throw('PR cant create Deferimento')
} }
return this.processes.postDeferimento(body) return this.processes.postDeferimento(body)
} }
@@ -57,8 +57,8 @@ export class PedidoService {
} }
arquivar({note = "", serialNumber, documents= [] }) { arquivar({note = "", serialNumber, documents= [] }) {
let body = { let body = {
"serialNumber": serialNumber, "serialNumber": serialNumber,
"action": "Arquivo", "action": "Arquivo",
"ActionTypeId": 95, "ActionTypeId": 95,
"dataFields": { "dataFields": {
+27 -5
View File
@@ -3,15 +3,20 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTr
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { SessionStore } from '../store/session.service'; import { SessionStore } from '../store/session.service';
import { AlertController, Platform } from '@ionic/angular'; import { AlertController, Platform } from '@ionic/angular';
import { PermissionService } from '../services/permission.service';
import { PermissionList } from '../models/permissionList';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class InactivityGuard implements CanActivate { export class InactivityGuard implements CanActivate {
permissionList = new PermissionList();
constructor( constructor(
private router:Router, private router:Router,
private platform: Platform, private platform: Platform,
public permissionService: PermissionService,
){} ){}
canActivate( canActivate(
@@ -19,17 +24,34 @@ export class InactivityGuard implements CanActivate {
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.platform.is('desktop') || this.platform.is('mobileweb')) { if (this.platform.is('desktop') || this.platform.is('mobileweb')) {
this.router.navigate(['/home/events']); if(this.permissionService.userPermission(this.permissionList.Agenda) || this.permissionService.userPermission(this.permissionList.Gabinete)){
this.router.navigate(['/home/events']);
}
else if(this.permissionService.userPermission(this.permissionList.Chat)){
this.router.navigate(['/home/chat']);
}
else if(this.permissionService.userPermission(this.permissionList.Actions)){
this.router.navigate(['/home/publications']);
}
return false return false
} else if(SessionStore.exist && SessionStore.user.Inactivity && !SessionStore.hasPin ) { } else if(SessionStore.exist && SessionStore.user.Inactivity && !SessionStore.hasPin ) {
return true return true
} else if(SessionStore.exist && !SessionStore.user.Inactivity) { } else if(SessionStore.exist && !SessionStore.user.Inactivity) {
return true return true
} else { }//Mobile or Tablet without session
this.router.navigate(['/home/events']); else {
if(this.permissionService.userPermission(this.permissionList.Agenda) || this.permissionService.userPermission(this.permissionList.Gabinete)){
this.router.navigate(['/home/events']);
}
else if(this.permissionService.userPermission(this.permissionList.Chat)){
this.router.navigate(['/home/chat']);
}
else if(this.permissionService.userPermission(this.permissionList.Actions)){
this.router.navigate(['/home/publications']);
}
return false return false
} }
} }
} }
+34 -31
View File
@@ -1,39 +1,42 @@
<ion-tabs class="tab"> <ion-tabs class="tab">
<ion-tab-bar class="bottoms" slot="bottom"> <ion-tab-bar class="bottoms" slot="bottom">
<ion-tab-button tab="events" [class.active]="pathname === '/home/events' ">
<!-- <ion-icon name="home"></ion-icon> -->
<ion-icon *ngIf="pathname != '/home/events'" class="nav-icon" src="assets/images/icons-nav-home.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/events'" class="nav-icon" src="assets/images/nav-hover/icons-nav-home-active.svg"></ion-icon>
<!-- <ion-badge color="danger">{{toDayEventStorage.eventsList.length + expedienteGdStore.count}}</ion-badge> -->
<ion-label>Início</ion-label>
</ion-tab-button>
<ion-tab-button tab="agenda" [class.active]="pathname === '/home/agenda' "> <ion-tab-button *ngIf="p.userPermission([permissionList.Agenda]) || p.userPermission([permissionList.Gabinete])" tab="events" [class.active]="pathname === '/home/events'">
<!-- <ion-icon name="calendar"></ion-icon> --> <!-- <ion-icon name="home"></ion-icon> -->
<ion-icon *ngIf="pathname != '/home/agenda'" class="nav-icon" src="assets/images/icons-nav-calendar.svg"></ion-icon> <ion-icon *ngIf="pathname != '/home/events'" class="nav-icon" src="assets/images/icons-nav-home.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/agenda'" class="nav-icon" src="assets/images/nav-hover/icons-nav-agenda-active.svg"></ion-icon> <ion-icon *ngIf="pathname == '/home/events'" class="nav-icon" src="assets/images/nav-hover/icons-nav-home-active.svg"></ion-icon>
<ion-label style="margin-bottom: 2px;" class="overflow-visible">Agenda</ion-label> <!-- <ion-badge color="danger">{{toDayEventStorage.eventsList.length + expedienteGdStore.count}}</ion-badge> -->
</ion-tab-button> <ion-label>Início</ion-label>
<ion-tab-button (click)="goto('/home/gabinete-digital')" [class.active]="pathname === '/home/gabinete-digital' "> </ion-tab-button>
<!-- <ion-icon name="file-tray-stacked"></ion-icon> -->
<ion-icon *ngIf="pathname != '/home/gabinete-digital'" class="nav-icon" src="assets/images/icons-nav-gabinete-inactive.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/gabinete-digital'" class="nav-icon" src="assets/images/nav-hover/icons-nav-gabinete-active.svg"></ion-icon>
<!-- <ion-badge color="danger" *ngIf="!p.userRole(['PR'])" >{{ documentCounterService.mdTotalDocument }}</ion-badge>
<ion-badge color="danger" *ngIf="p.userRole(['PR'])" >{{ documentCounterService.prTotalDocument }}</ion-badge> -->
<ion-label>Gabinete</ion-label>
</ion-tab-button>
<ion-tab-button tab="publications" [class.active]="pathname === '/home/publications' "> <ion-tab-button *ngIf="p.userPermission([permissionList.Agenda])" tab="agenda" [class.active]="pathname === '/home/agenda' ">
<ion-icon *ngIf="pathname != '/home/publications'" class="nav-icon" src="assets/images/icons-nav-actions.svg"></ion-icon> <!-- <ion-icon name="calendar"></ion-icon> -->
<ion-icon *ngIf="pathname == '/home/publications'" class="nav-icon" src="assets/images/nav-hover/icons-nav-actions-active.svg"></ion-icon> <ion-icon *ngIf="pathname != '/home/agenda'" class="nav-icon" src="assets/images/icons-nav-calendar.svg"></ion-icon>
<ion-label style="margin-bottom: 2px;" class="overflow-visible">Ações</ion-label> <ion-icon *ngIf="pathname == '/home/agenda'" class="nav-icon" src="assets/images/nav-hover/icons-nav-agenda-active.svg"></ion-icon>
</ion-tab-button> <ion-label style="margin-bottom: 2px;" class="overflow-visible">Agenda</ion-label>
<ion-tab-button tab="chat" [class.active]="pathname === '/home/chat' "> </ion-tab-button>
<ion-icon *ngIf="pathname != '/home/chat'" class="nav-icon" src="assets/images/icons-nav-chat-inactive.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/chat'" class="nav-icon" src="assets/images/nav-hover/icons-nav-chat-active.svg"></ion-icon> <ion-tab-button *ngIf="p.userPermission([permissionList.Gabinete])" (click)="goto('/home/gabinete-digital')" [class.active]="pathname === '/home/gabinete-digital' ">
<ion-label>Chat</ion-label> <!-- <ion-icon name="file-tray-stacked"></ion-icon> -->
</ion-tab-button> <ion-icon *ngIf="pathname != '/home/gabinete-digital'" class="nav-icon" src="assets/images/icons-nav-gabinete-inactive.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/gabinete-digital'" class="nav-icon" src="assets/images/nav-hover/icons-nav-gabinete-active.svg"></ion-icon>
<!-- <ion-badge color="danger" *ngIf="!p.userRole(['PR'])" >{{ documentCounterService.mdTotalDocument }}</ion-badge>
<ion-badge color="danger" *ngIf="p.userRole(['PR'])" >{{ documentCounterService.prTotalDocument }}</ion-badge> -->
<ion-label>Gabinete</ion-label>
</ion-tab-button>
<ion-tab-button *ngIf="p.userPermission([permissionList.Actions])" tab="publications" [class.active]="pathname === '/home/publications' ">
<ion-icon *ngIf="pathname != '/home/publications'" class="nav-icon" src="assets/images/icons-nav-actions.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/publications'" class="nav-icon" src="assets/images/nav-hover/icons-nav-actions-active.svg"></ion-icon>
<ion-label style="margin-bottom: 2px;" class="overflow-visible">Ações</ion-label>
</ion-tab-button>
<ion-tab-button *ngIf="p.userPermission([permissionList.Actions])" tab="chat" [class.active]="pathname === '/home/chat' ">
<ion-icon *ngIf="pathname != '/home/chat'" class="nav-icon" src="assets/images/icons-nav-chat-inactive.svg"></ion-icon>
<ion-icon *ngIf="pathname == '/home/chat'" class="nav-icon" src="assets/images/nav-hover/icons-nav-chat-active.svg"></ion-icon>
<ion-label>Chat</ion-label>
</ion-tab-button>
</ion-tab-bar> </ion-tab-bar>
</ion-tabs> </ion-tabs>
+12 -3
View File
@@ -16,7 +16,7 @@ import { StorageService } from '../services/storage.service';
import { File } from '@ionic-native/file/ngx'; import { File } from '@ionic-native/file/ngx';
/* import { WebNotificationPopupService } from '../services/notification/web-notification-popup.service'; */ /* import { WebNotificationPopupService } from '../services/notification/web-notification-popup.service'; */
import { DocumentCounterService } from '../services/worker/document-counter.service'; import { DocumentCounterService } from '../services/worker/document-counter.service';
import { PermissionService } from '../services/worker/permission.service'; import { PermissionService } from '../services/permission.service';
import { BackgroundService } from 'src/app/services/background.service'; import { BackgroundService } from 'src/app/services/background.service';
import { OfflineManagerService } from 'src/app/services/offline-manager.service'; import { OfflineManagerService } from 'src/app/services/offline-manager.service';
import { Storage } from '@ionic/storage'; import { Storage } from '@ionic/storage';
@@ -30,6 +30,8 @@ import { WsChatService } from 'src/app/services/chat/ws-chat.service';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { NativeNotificationService } from 'src/app/services/native-notification.service'; import { NativeNotificationService } from 'src/app/services/native-notification.service';
import { UserSession } from '../models/user.model';
import { PermissionList } from '../models/permissionList';
@Component({ @Component({
selector: 'app-home', selector: 'app-home',
@@ -79,6 +81,8 @@ export class HomePage implements OnInit {
status: string = ""; status: string = "";
audioName: string = ""; audioName: string = "";
public user: UserSession;
permissionList = new PermissionList();
constructor( constructor(
private router: Router, private router: Router,
@@ -102,12 +106,17 @@ export class HomePage implements OnInit {
private sqliteservice: SqliteService, private sqliteservice: SqliteService,
public RouteService: RouteService, public RouteService: RouteService,
private WsChatService: WsChatService, private WsChatService: WsChatService,
private NativeNotificationService: NativeNotificationService,) { private NativeNotificationService: NativeNotificationService,
) {
if (SessionStore.exist) {
this.user = SessionStore.user;
}
/* this.webNotificationPopupService.askNotificationPermission() */ /* this.webNotificationPopupService.askNotificationPermission() */
this.NativeNotificationService.askForPermission() this.NativeNotificationService.askForPermission()
this.router.events.subscribe((val) => { this.router.events.subscribe((val) => {
document.querySelectorAll('ion-modal').forEach((e: any) => e.remove()) document.querySelectorAll('ion-modal').forEach((e: any) => e.remove())
document.querySelectorAll('popover-viewport').forEach((e: any) => e.remove()) document.querySelectorAll('popover-viewport').forEach((e: any) => e.remove())
@@ -16,7 +16,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormControl, FormGroup, Validators } from '@angular/forms';
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker'; import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker'; import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { DespachoService } from 'src/app/Rules/despacho.service'; import { DespachoService } from 'src/app/Rules/despacho.service';
import { PedidoService } from 'src/app/Rules/pedido.service' import { PedidoService } from 'src/app/Rules/pedido.service'
import { fullTask } from 'src/app/models/dailyworktask.model'; import { fullTask } from 'src/app/models/dailyworktask.model';
@@ -7,7 +7,7 @@ import { ExpedientTaskModalPage } from 'src/app/pages/gabinete-digital/expedient
import { DocumentSetUpMeetingPage } from '../document-set-up-meeting/document-set-up-meeting.page'; import { DocumentSetUpMeetingPage } from '../document-set-up-meeting/document-set-up-meeting.page';
import { SearchDocumentDetails, SearchFolderDetails } from 'src/app/models/search-document'; import { SearchDocumentDetails, SearchFolderDetails } from 'src/app/models/search-document';
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage'; import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { SearchedDocumentOptionsPage } from 'src/app/shared/popover/searched-document-options/searched-document-options.page'; import { SearchedDocumentOptionsPage } from 'src/app/shared/popover/searched-document-options/searched-document-options.page';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { ViewDocumentPage } from '../view-document/view-document.page'; import { ViewDocumentPage } from '../view-document/view-document.page';
@@ -132,7 +132,7 @@ export class DocumentDetailPage implements OnInit {
} }
async viewDocumentModal() { async viewDocumentModal() {
const selectedDoc = this.LoadedDocument.Documents[ this.dicIndex] const selectedDoc = this.LoadedDocument.Documents[ this.dicIndex]
let task = { let task = {
+15 -14
View File
@@ -1,7 +1,7 @@
import { models } from 'beast-orm' import { models } from 'beast-orm'
import { AESEncrypt } from '../services/aesencrypt.service' import { AESEncrypt } from '../services/aesencrypt.service'
const _AESEncrypt = new AESEncrypt() const _AESEncrypt = new AESEncrypt()
const { ArrayField, JsonField} = models.indexedDB.fields const { ArrayField, JsonField} = models.indexedDB.fields
export class MessageModel extends models.Model { export class MessageModel extends models.Model {
@@ -10,35 +10,36 @@ export class MessageModel extends models.Model {
mentions = ArrayField() mentions = ArrayField()
msg = models.CharField() msg = models.CharField()
rid = models.CharField() rid = models.CharField()
ts = models.CharField() ts = JsonField({blank:true})
u = JsonField() u = JsonField()
_id = models.CharField({unique:true}) _id = models.CharField({blank:true})
_updatedAt = models.CharField() _updatedAt = models.IntegerField()
messageSend = models.BooleanField() messageSend = models.BooleanField()
offline = models.BooleanField() offline = models.BooleanField()
viewed = ArrayField() viewed = ArrayField({blank:true})
received = ArrayField() received = ArrayField({blank:true})
localReference = models.CharField({blank:true}) localReference = models.CharField({blank:true})
attachments = ArrayField() attachments = ArrayField({blank:true})
file = ArrayField() file = JsonField({blank:true})
} }
export class DeleteMessageModel extends models.Model { export class DeleteMessageModel extends models.Model {
messageId = models.IntegerField() messageId = models.CharField()
rid = models.CharField() rid = models.CharField()
ts = models.CharField()
u = JsonField() u = JsonField()
needToReceiveBy = ArrayField() needToReceiveBy = ArrayField()
} }
models.register({ models.register({
databaseName: 'chat-storage', databaseName: 'chat-storage',
type: 'indexedDB', type: 'indexedDB',
version: 1, version: 4,
models: [MessageModel, DeleteMessageModel] models: [MessageModel, DeleteMessageModel]
}) })
window['MessageModel'] = MessageModel
+6
View File
@@ -0,0 +1,6 @@
export class PermissionList{
Agenda = 530;
Gabinete = 531;
Actions = 534;
Chat = 541;
}
+7 -5
View File
@@ -2,12 +2,12 @@ export class UserForm {
username: string; username: string;
password: string; password: string;
domainName: string; domainName: string;
BasicAuthKey: string; BasicAuthKey: string;
} }
export class LoginUserRespose { export class LoginUserRespose {
BasicAuthKey: string; BasicAuthKey: string;
UserId: number; UserId: number;
Authorization: string; Authorization: string;
Email: string Email: string
@@ -30,11 +30,12 @@ export class LoginUserRespose {
}[] }[]
UserName: string UserName: string
Profile: any; Profile: any;
UserPermissions: any;
} }
export class UserSession { export class UserSession {
BasicAuthKey: string; BasicAuthKey: string;
UserId: number; UserId: number;
Authorization: string; Authorization: string;
Email: string Email: string
@@ -63,5 +64,6 @@ export class UserSession {
LoginPreference: 'None' | 'Password' | 'Pin' | null; LoginPreference: 'None' | 'Password' | 'Pin' | null;
PIN: string PIN: string
Inactivity: boolean Inactivity: boolean
UrlBeforeInactivity: string UrlBeforeInactivity: string;
} UserPermissions: any;
}
@@ -102,7 +102,10 @@
<div class="message"> <div class="message">
<div *ngIf="msg.attachments" class="message-attachments"> <div *ngIf="msg.attachments" class="message-attachments">
<div *ngFor="let file of msg.attachments"> <div *ngFor="let file of msg.attachments">
<div *ngIf="msg.file.type == 'application/img'" (click)="openPreview(msg)"> <div *ngIf="msg.file.type == 'application/img' && !msg.attachments[0].image_url">
NOT UPLOADED
</div>
<div *ngIf="msg.file.type == 'application/img' && msg.attachments[0].image_url" (click)="openPreview(msg)">
<img *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image" > <img *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-icon *ngIf="msg.attachments[0].image_url == null" name="download-outline"></ion-icon>
</div> </div>
@@ -118,7 +121,15 @@
<ion-label class="file-title">{{file.title}}</ion-label> <ion-label class="file-title">{{file.title}}</ion-label>
</div> </div>
</div> </div>
<div *ngIf="msg.file.type == 'application/audio'"> <div 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>{{file.title}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></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" class="d-flex width-100" controls controlsList="nodownload noplaybackrate"></audio> <audio [src]="file.title_link|safehtml" preload="metadata" class="d-flex width-100" controls controlsList="nodownload noplaybackrate"></audio>
</div> </div>
<div class="file-details-optional add-attachment-bg-color"> <div class="file-details-optional add-attachment-bg-color">
@@ -193,7 +204,7 @@
</ion-content> </ion-content>
<ion-footer> <ion-footer>
<div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true"> <div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true">
<ngx-letters-avatar *ngIf="showAvatar" <ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name" [avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name"
@@ -35,6 +35,7 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder';
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { MessageService } from 'src/app/services/chat/message.service';
@Component({ @Component({
selector: 'app-group-messages', selector: 'app-group-messages',
@@ -43,8 +44,6 @@ import { DomSanitizer } from '@angular/platform-browser';
}) })
export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
showLoader: boolean; showLoader: boolean;
isGroupCreated: boolean; isGroupCreated: boolean;
loggedUser: any; loggedUser: any;
@@ -252,15 +251,49 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.lastAudioRecorded = fileName; this.lastAudioRecorded = fileName;
}) })
this.storage.get('recordData').then((recordData) => { try {
console.log(recordData); this.storage.get('recordData').then((recordData) => {
if(recordData.value.recordDataBase64.includes('data:audio')){ console.log(recordData);
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); if(recordData?.value?.recordDataBase64.includes('data:audio')){
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64);
}
else{
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`);
}
});
} catch (error) {}
}
stopRecording() {
this.deleteRecording();
this.allowTyping = false;
console.log('Stop');
if (!this.recording) {
return;
}
this.recording = false;
VoiceRecorder.stopRecording().then(async (result: RecordingData) => {
console.log('==================================',result);
this.recording = false;
if (result.value && result.value.recordDataBase64) {
const recordData = result.value.recordDataBase64;
//console.log(recordData);
const fileName = new Date().getTime() + ".mp3";
//Save file
await this.storage.set('fileName',fileName)
this.storage.set('recordData',result).then(() => {
console.log('Audio recorded saved', result);
setTimeout(async () => {
this.loadFiles();
}, 1000);
})
} }
else{ })
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`);
}
});
} }
startRecording() { startRecording() {
@@ -274,32 +307,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.calculateDuration(); this.calculateDuration();
} }
stopRecording() {
this.deleteRecording();
this.allowTyping = false;
console.log('Stop');
if (!this.recording) {
return;
}
this.recording = false;
VoiceRecorder.stopRecording().then(async (result: RecordingData) => {
console.log(result);
this.recording = false;
if (result.value && result.value.recordDataBase64) {
const recordData = result.value.recordDataBase64;
//console.log(recordData);
const fileName = new Date().getTime() + ".mp3";
//Save file
this.storage.set('fileName',fileName);
this.storage.set('recordData',result).then(() => {
console.log('Audio recorded saved');
})
}
})
setTimeout(async () => {
this.loadFiles();
}, 1000);
}
async deleteRecording(){ async deleteRecording(){
this.storage.remove('fileName'); this.storage.remove('fileName');
@@ -364,7 +372,6 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
} }
async getChatMembers() { async getChatMembers() {
//return await this.chatService.getMembers(roomId).toPromise();
this.chatService.getAllUsers().subscribe(res => { this.chatService.getAllUsers().subscribe(res => {
console.log(res); console.log(res);
@@ -428,41 +435,64 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.wsChatMethodsService.getGroupRoom(this.roomId).send({}) this.wsChatMethodsService.getGroupRoom(this.roomId).send({})
} }
base64toBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
async sendAudio(fileName) { async sendAudio(fileName) {
const roomId = this.roomId const roomId = this.roomId
let audioFile;
this.storage.get('recordData').then((recordData) => { this.storage.get('recordData').then((recordData) => {
console.log(recordData); console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){ audioFile = recordData;
this.audioRecorded = recordData.value.recordDataBase64; if(recordData?.value?.recordDataBase64.includes('data:audio')){
this.audioRecorded = recordData?.value?.recordDataBase64;
} }
else{ else{
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`;
} }
});
//Converting base64 to blob //Converting base64 to blob
const base64Response = await fetch(this.audioRecorded); const encodedData = btoa(this.audioRecorded);
const blob = await base64Response.blob(); const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
console.log(blob)
const formData = new FormData(); const formData = new FormData();
formData.append("blobFile", blob); formData.append("blobFile", blob);
this.wsChatMethodsService.getGroupRoom(roomId).send({ this.wsChatMethodsService.getGroupRoom(roomId).send({
file: { file: {
"type": "application/audio", "type": "application/audio",
/* "guid": '', */ "msDuration":audioFile.value.msDuration,
"mimeType":audioFile.value.mimeType,
}, },
attachments: [{ attachments: [{
"title": fileName , "title": fileName ,
"title_link": this.audioRecorded,
"title_link_download": true, "title_link_download": true,
"type": "file" "type": "audio"
}], }],
temporaryData: formData temporaryData: formData
}) })
this.deleteRecording();
});
this.deleteRecording();
} }
@@ -950,40 +980,11 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
card.el.style['z-index'] = 11; card.el.style['z-index'] = 11;
} }
downloadFileMsg(msg) { downloadFileMsg(msg: MessageService) {
console.log('FILE TYPE', msg.file.type) msg.downloadFileMsg()
this.downloadFile = "";
// if (msg.file.type == "application/img") {
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
console.log('FILE TYPE 22', msg.file.guid)
var name = msg.file.guid;
if (event.type === HttpEventType.DownloadProgress) {
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
console.log('FILE TYPE 33', msg.file.type)
} else if (event.type === HttpEventType.Response) {
if (msg.file.type == "application/img") {
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
} else {
this.downloadFile = event.body;
}
msg.attachments[0] = {
image_url: this.downloadFile,
name: msg.attachments[0].name,
title: msg.attachments[0].title,
title_link_download: msg.attachments[0].title_link_download,
ts: msg.attachments[0].ts
}
this.sqlservice.updateChatMsg(msg._id, this.downloadFile);
}
});
console.log('FILE TYPE 44', this.downloadFile)
//}
} }
async openPreview(msg) { async openPreview(msg: MessageService) {
if (!msg.attachments[0].image_url ||msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { if (!msg.attachments[0].image_url ||msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') {
this.downloadFileMsg(msg) this.downloadFileMsg(msg)
@@ -1003,5 +1004,12 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
} }
} }
async audioPreview(msg) {
console.log(msg);
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
this.downloadFileMsg(msg)
} else {}
}
} }
+89 -43
View File
@@ -1,4 +1,4 @@
<ion-header class="ion-no-border"> <ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar"> <ion-toolbar class="header-toolbar">
<!-- <div #rectangle class="rectangle" (press)="handlePress()"> <!-- <div #rectangle class="rectangle" (press)="handlePress()">
Double click me to change the color Double click me to change the color
@@ -26,14 +26,15 @@
<div hidden class="right"> <div hidden class="right">
<button class="btn-no-color" (click)="openMessagesOptions()"> <button class="btn-no-color" (click)="openMessagesOptions()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-menu.svg"></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg"></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg">
</ion-icon>
</button> </button>
</div> </div>
</div> </div>
<div hidden class="header-bottom" (click)="addContacts()"> <div hidden class="header-bottom" (click)="addContacts()">
<div class="header-bottom-icon"> <div class="header-bottom-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-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> <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
</div> </div>
<div class="header-bottom-contacts"> <div class="header-bottom-contacts">
<ion-label class="text-color-blue">Adicionar contacto</ion-label> <ion-label class="text-color-blue">Adicionar contacto</ion-label>
@@ -51,8 +52,11 @@
</ion-refresher-content> </ion-refresher-content>
</ion-refresher> --> </ion-refresher> -->
<div (click)="handleClick()" class="messages" #scrollMe> <div (click)="handleClick()" class="messages" #scrollMe>
<div class="messages-list-item-wrapper container-width-100" *ngFor="let msg of wsChatMethodsService.getDmRoom(this.roomId).messages; let last = last" [class.messages-list-item-wrapper-active]="msg._id == selectedMsgId" > <div class="messages-list-item-wrapper container-width-100"
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' (click)="downloadFileMsg(msg)" *ngIf="msg.msg !=''"> *ngFor="let msg of wsChatMethodsService.getDmRoom(this.roomId).messages; let last = last"
[class.messages-list-item-wrapper-active]="msg._id == selectedMsgId">
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}'
*ngIf="msg.msg !=''">
<div class="title"> <div class="title">
<ion-label (click)="hkellor()">{{msg.u.name}}</ion-label> <ion-label (click)="hkellor()">{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span> <span class="time">{{msg.duration}}</span>
@@ -83,44 +87,74 @@
<div (click)="docIndex(i); openPreview(msg)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file"> <div (click)="docIndex(i); openPreview(msg)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
<span *ngIf="msg.file.type"> <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/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/word'" icon="file-word" class="word-icon">
<fa-icon *ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'" icon="file-word" class="excel-icon"></fa-icon> </fa-icon>
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-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> </span>
<ion-label class="file-title">{{file.title}}</ion-label> <ion-label class="file-title">{{file.title}}</ion-label>
</div> </div>
</div> </div>
<div *ngIf="msg.file.type == 'application/audio'"> <div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
<audio [src]="file.title_link|safehtml" preload="metadata" class="d-flex width-100" controls controlsList="nodownload noplaybackrate"></audio> <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>{{file.title}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></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" class="d-flex width-100" controls
controlsList="nodownload noplaybackrate"></audio>
</div> </div>
<div class="file-details-optional add-attachment-bg-color"> <div class="file-details-optional add-attachment-bg-color">
<ion-label *ngIf="msg.file && msg.file != ''"> <ion-label *ngIf="msg.file && msg.file != ''">
<span *ngIf="file.description">{{file.description}}</span> <span *ngIf="file.description">{{file.description}}</span>
<span *ngIf="file.description && msg.file.type != 'application/webtrix'"></span> <span *ngIf="file.description && msg.file.type != 'application/webtrix'"></span>
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span> <span
*ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label> </ion-label>
</div> </div>
</div>
</div> </div>
</div> </div>
{{last ? scrollToBottom() : ''}}
</div> </div>
{{last ? scrollToBottom() : ''}}
</div> </div>
</div> <div *ngIf="msg.file.type == 'application/meeting'" class="info-meeting">
<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 />
<ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br /> <button (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal">
<button (click)="goToEvent(msg.file.id)" 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-normal">{{msg.file.subject}}</ion-label>
<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 /> </button><br />
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</ion-label><br /> <ion-label class="info-meeting-medium">
</div> <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>
<div *ngIf="msg.file && msg.delate == false"> <div *ngIf="msg.file && msg.delate == false">
<div *ngIf="msg.file.type == 'application/meeting'" class="info-meeting"> <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 /> <ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal"><ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label></button><br /> <button (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal">
<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-normal">{{msg.file.subject}}</ion-label>
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</ion-label><br /> </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>
{{last ? scrollToBottom() : ''}} {{last ? scrollToBottom() : ''}}
</div> </div>
@@ -164,24 +198,24 @@
<ion-footer > <ion-footer >
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true"> <div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true">
<ngx-letters-avatar <ngx-letters-avatar [avatarName]="wsChatMethodsService.getGroupRoom(roomId).name" [width]="30" [circular]="true"
[avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name" fontFamily="Roboto"></ngx-letters-avatar>
[width]="30"
[circular]="true"
fontFamily="Roboto"></ngx-letters-avatar>
está a escrever ... está a escrever ...
</div> </div>
<div class="width-100 pl-20 pr-20"> <div class="width-100 pl-20 pr-20">
<span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span> <span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span>
<audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls controlsList="nodownload noplaybackrate"></audio> <audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls
controlsList="nodownload noplaybackrate"></audio>
</div> </div>
<div class="container width-100 d-flex"> <div class="container width-100 d-flex">
<div> <div>
<button *ngIf="!recording && !lastAudioRecorded && allowTyping" class="btn-no-color" (click)="openChatOptions()"> <button *ngIf="!recording && !lastAudioRecorded && allowTyping" class="btn-no-color" (click)="openChatOptions()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-options" src="assets/images/icons-add.svg"></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-options"
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-options" src="assets/images/theme/gov/icons-add.svg"></ion-icon> src="assets/images/icons-add.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-options"
src="assets/images/theme/gov/icons-add.svg"></ion-icon>
</button> </button>
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-no-color" (click)="deleteRecording()"> <button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-no-color" (click)="deleteRecording()">
<fa-icon class="icon-size-27" icon="trash"></fa-icon> <fa-icon class="icon-size-27" icon="trash"></fa-icon>
@@ -189,26 +223,38 @@
</div> </div>
<div class="width-70 message-container"> <div class="width-70 message-container">
<div *ngIf="!recording && !lastAudioRecorded" class="type-message"> <div *ngIf="!recording && !lastAudioRecorded" class="type-message">
<ion-textarea *ngIf="allowTyping" autocomplete="on" autocorrect="on" spellcheck="true" clearOnEdit="true" placeholder="Escrever uma mensagem" auto-grow class="message-input" rows="1" [(ngModel)]="wsChatMethodsService.getDmRoom(roomId).message" (ionChange)="wsChatMethodsService.getDmRoom(roomId).sendTyping()"></ion-textarea> <ion-textarea *ngIf="allowTyping" autocomplete="on" autocorrect="on" spellcheck="true" clearOnEdit="true"
placeholder="Escrever uma mensagem" auto-grow class="message-input" rows="1"
[(ngModel)]="wsChatMethodsService.getDmRoom(roomId).message"
(ionChange)="wsChatMethodsService.getDmRoom(roomId).sendTyping()"></ion-textarea>
</div> </div>
<div *ngIf="recording" class="d-flex align-items-center justify-content-center"> <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"> <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> <ion-icon class="icon-size-45" name="stop-circle-outline" color="danger"></ion-icon>
</button> </button>
</div> </div>
</div> </div>
<div> <div>
<button #recordbtn *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && !lastAudioRecorded" (click)="startRecording()" class="btn-no-color"> <button #recordbtn *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && !lastAudioRecorded"
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/default/icons-chat-record-audio.svg"></ion-icon> (click)="startRecording()" class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-record-audio.svg"></ion-icon> <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>
<button *ngIf="wsChatMethodsService.getDmRoom(roomId).message" class="btn-no-color" (click)="sendMessage()" class="btn-no-color"> <button *ngIf="wsChatMethodsService.getDmRoom(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> class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon> <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>
<button *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && lastAudioRecorded" (click)="sendAudio(lastAudioRecorded)" class="btn-no-color"> <button *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && lastAudioRecorded"
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon> (click)="sendAudio(lastAudioRecorded)" class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon> <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>
</div> </div>
</div> </div>
+57 -43
View File
@@ -219,15 +219,19 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.lastAudioRecorded = fileName; this.lastAudioRecorded = fileName;
}) })
this.storage.get('recordData').then((recordData) => { try {
console.log(recordData); this.storage.get('recordData').then((recordData) => {
if(recordData.value.recordDataBase64.includes('data:audio')){ console.log(recordData);
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); if(recordData?.value?.recordDataBase64.includes('data:audio')){
} this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64);
else{ }
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`); else{
} this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`);
}); }
});
} catch (error) {}
} }
startRecording() { startRecording() {
@@ -380,41 +384,65 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.wsChatMethodsService.getDmRoom(this.roomId).send({}) this.wsChatMethodsService.getDmRoom(this.roomId).send({})
} }
async sendAudio(fileName) { base64toBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
async sendAudio(fileName) {
const roomId = this.roomId const roomId = this.roomId
let audioFile;
this.storage.get('recordData').then((recordData) => { this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){ audioFile = recordData;
this.audioRecorded = recordData.value.recordDataBase64; if(recordData?.value?.recordDataBase64.includes('data:audio')){
this.audioRecorded = recordData?.value?.recordDataBase64;
} }
else{ else{
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`;
} }
});
console.log(this.audioRecorded);
//Converting base64 to blob //Converting base64 to blob
const base64Response = await fetch(this.audioRecorded); const encodedData = btoa(this.audioRecorded);
const blob = await base64Response.blob(); const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
console.log(blob)
const formData = new FormData(); const formData = new FormData();
formData.append("blobFile", blob); formData.append("blobFile", blob);
this.wsChatMethodsService.getDmRoom(roomId).send({ this.wsChatMethodsService.getDmRoom(roomId).send({
file: { file: {
"type": "application/audio", "type": "application/audio",
/* "guid": '', */ "msDuration":audioFile.value.msDuration,
"mimeType":audioFile.value.mimeType,
}, },
attachments: [{ attachments: [{
"title": fileName , "title": fileName ,
"title_link": this.audioRecorded,
"title_link_download": true, "title_link_download": true,
"type": "file" "type": "audio"
}], }],
temporaryData: formData temporaryData: formData
}) })
this.deleteRecording();
});
this.deleteRecording();
} }
@@ -824,27 +852,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
} }
base64toBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
getBase64(file) { getBase64(file) {
var reader = this.getFileReader(); var reader = this.getFileReader();
reader.readAsDataURL(file); reader.readAsDataURL(file);
@@ -1081,6 +1088,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
} }
async audioPreview(msg) {
console.log(msg);
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
this.downloadFileMsg(msg)
} else {}
}
imageSize(img) { imageSize(img) {
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
@@ -16,7 +16,7 @@ import { DespachoService } from 'src/app/Rules/despacho.service'
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { fullTask } from 'src/app/models/dailyworktask.model'; import { fullTask } from 'src/app/models/dailyworktask.model';
import { AttachmentList } from 'src/app/models/Excludetask'; import { AttachmentList } from 'src/app/models/Excludetask';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page'; import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { SqliteService } from 'src/app/services/sqlite.service'; import { SqliteService } from 'src/app/services/sqlite.service';
@@ -359,8 +359,8 @@ export class DespachoPage implements OnInit {
} }
async generateDiploma(note:string, documents:any) { async generateDiploma(note:string, documents:any) {
let body = { let body = {
"serialNumber": this.serialnumber, "serialNumber": this.serialnumber,
"action": "Reencaminhar", "action": "Reencaminhar",
"ActionTypeId": 99999839, "ActionTypeId": 99999839,
"dataFields": { "dataFields": {
@@ -22,7 +22,7 @@ import { ExpedienteService } from 'src/app/Rules/expediente.service';
import { expedienteTask } from 'src/app/models/dailyworktask.model'; import { expedienteTask } from 'src/app/models/dailyworktask.model';
import { TaskService } from 'src/app/Rules/task.service'; import { TaskService } from 'src/app/Rules/task.service';
import { DocumentViewerPage } from 'src/app/modals/document-viewer/document-viewer.page'; import { DocumentViewerPage } from 'src/app/modals/document-viewer/document-viewer.page';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page'; import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service' import { ThemeService } from 'src/app/services/theme.service'
@@ -165,7 +165,7 @@ export class ExpedienteDetailPage implements OnInit {
this.onlinecheck = false; this.onlinecheck = false;
this.sqliteservice.getProcessById(this.serialNumber).then((process) => { this.sqliteservice.getProcessById(this.serialNumber).then((process) => {
console.log("expedient ditail", process) console.log("expedient ditail", process)
var workflow = JSON.parse(process[0].workflowInstanceDataFields); var workflow = JSON.parse(process[0].workflowInstanceDataFields);
var origina var origina
if (process[0].originator === "undefined") { if (process[0].originator === "undefined") {
@@ -173,7 +173,7 @@ export class ExpedienteDetailPage implements OnInit {
} else { } else {
origina = JSON.parse(process[0].originator) origina = JSON.parse(process[0].originator)
} }
this.task = { this.task = {
"SerialNumber": process[0].serialNumber, "SerialNumber": process[0].serialNumber,
"Folio": workflow.Subject, "Folio": workflow.Subject,
@@ -191,7 +191,7 @@ export class ExpedienteDetailPage implements OnInit {
"AttachmentsProcessLastInstanceID": workflow.AttachmentsProcessLastInstanceID, "AttachmentsProcessLastInstanceID": workflow.AttachmentsProcessLastInstanceID,
"InstanceID": workflow.InstanceID "InstanceID": workflow.InstanceID
} }
this.fulltask = { this.fulltask = {
Documents: JSON.parse(process[0].Documents), Documents: JSON.parse(process[0].Documents),
actions: JSON.parse(process[0].actions), actions: JSON.parse(process[0].actions),
@@ -209,11 +209,11 @@ export class ExpedienteDetailPage implements OnInit {
workflowInstanceID: process[0].workflowInstanceID, workflowInstanceID: process[0].workflowInstanceID,
workflowName: process[0].workflowName, workflowName: process[0].workflowName,
} }
}) })
}) })
} }
} }
@@ -11,7 +11,7 @@
<div class="main-content d-flex height-100 border-t-radius"> <div class="main-content d-flex height-100 border-t-radius">
<!-- Aside left --> <!-- Aside left -->
<div class="aside-wrapper d-flex flex-column width-md-40 flex-grow-1"> <div class="aside-wrapper d-flex flex-column width-md-40 flex-grow-1">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar> <ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<div class="title-container"> <div class="title-container">
<div class="title"> <div class="title">
@@ -22,7 +22,7 @@ import { CustomTaskPipe } from 'src/app/pipes/custom-task.pipe';
//import { NotificationsService } from 'src/app/services/notifications.service'; //import { NotificationsService } from 'src/app/services/notifications.service';
import { DespachoService } from 'src/app/Rules/despacho.service'; import { DespachoService } from 'src/app/Rules/despacho.service';
import { ChangeProfileService } from 'src/app/services/change-profile.service'; import { ChangeProfileService } from 'src/app/services/change-profile.service';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ThemeService } from 'src/app/services/theme.service' import { ThemeService } from 'src/app/services/theme.service'
@@ -115,6 +115,9 @@ export class GabineteDigitalPage implements OnInit, DoCheck {
customTaskPipe = new CustomTaskPipe() customTaskPipe = new CustomTaskPipe()
permissions = {
Agenda: 530
}
@ViewChild(ExpedientsPage) expedientesPage: ExpedientsPage; @ViewChild(ExpedientsPage) expedientesPage: ExpedientsPage;
@ViewChild(PendentesPage) pendentesListPage: PendentesPage; @ViewChild(PendentesPage) pendentesListPage: PendentesPage;
@ViewChild(EventsToApprovePage) eventsToApprove: EventsToApprovePage; @ViewChild(EventsToApprovePage) eventsToApprove: EventsToApprovePage;
@@ -256,7 +259,7 @@ export class GabineteDigitalPage implements OnInit, DoCheck {
let date = new Date(element.taskStartDate); let date = new Date(element.taskStartDate);
date.setMonth(date.getMonth() + 1); date.setMonth(date.getMonth() + 1);
let taskDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); let taskDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
let task = { let task = {
"SerialNumber": element.serialNumber, "SerialNumber": element.serialNumber,
"Folio": element.workflowInstanceDataFields.Subject, "Folio": element.workflowInstanceDataFields.Subject,
@@ -274,11 +277,11 @@ export class GabineteDigitalPage implements OnInit, DoCheck {
"Agenda": element.workflowInstanceDataFields.Agenda, "Agenda": element.workflowInstanceDataFields.Agenda,
"customDate": this.setFormatDate(new Date(element.workflowInstanceDataFields.StartDate), new Date(element.workflowInstanceDataFields.EndDate), element.workflowInstanceDataFields.IsAllDayEvent), "customDate": this.setFormatDate(new Date(element.workflowInstanceDataFields.StartDate), new Date(element.workflowInstanceDataFields.EndDate), element.workflowInstanceDataFields.IsAllDayEvent),
} }
this.allProcessesList.push(task); this.allProcessesList.push(task);
this.allProcessesList = removeDuplicate(this.allProcessesList); this.allProcessesList = removeDuplicate(this.allProcessesList);
this.allProcessesList = this.sortService.sortDate(this.allProcessesList, 'CreateDate') this.allProcessesList = this.sortService.sortDate(this.allProcessesList, 'CreateDate')
}); });
}) })
} else { } else {
@@ -287,9 +290,9 @@ export class GabineteDigitalPage implements OnInit, DoCheck {
let date = new Date(element.taskStartDate); let date = new Date(element.taskStartDate);
date.setMonth(date.getMonth() + 1); date.setMonth(date.getMonth() + 1);
let taskDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); let taskDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
var workflowInstanceDataFields = JSON.parse(element.workflowInstanceDataFields); var workflowInstanceDataFields = JSON.parse(element.workflowInstanceDataFields);
let task = { let task = {
"SerialNumber": element.serialNumber, "SerialNumber": element.serialNumber,
"Folio": workflowInstanceDataFields.Subject, "Folio": workflowInstanceDataFields.Subject,
@@ -306,11 +309,11 @@ export class GabineteDigitalPage implements OnInit, DoCheck {
"Agenda": workflowInstanceDataFields.Agenda, "Agenda": workflowInstanceDataFields.Agenda,
"customDate": this.setFormatDate(new Date(workflowInstanceDataFields.StartDate), new Date(workflowInstanceDataFields.EndDate), workflowInstanceDataFields.IsAllDayEvent), "customDate": this.setFormatDate(new Date(workflowInstanceDataFields.StartDate), new Date(workflowInstanceDataFields.EndDate), workflowInstanceDataFields.IsAllDayEvent),
} }
this.allProcessesList.push(task); this.allProcessesList.push(task);
this.allProcessesList = removeDuplicate(this.allProcessesList) this.allProcessesList = removeDuplicate(this.allProcessesList)
this.allProcessesList = this.sortService.sortDate(this.allProcessesList, 'CreateDate') this.allProcessesList = this.sortService.sortDate(this.allProcessesList, 'CreateDate')
}); });
console.log("All process from db ", allprocess) console.log("All process from db ", allprocess)
}) })
@@ -23,7 +23,7 @@ import { PedidoService } from 'src/app/Rules/pedido.service';
import { SqliteService } from 'src/app/services/sqlite.service'; import { SqliteService } from 'src/app/services/sqlite.service';
import { BackgroundService } from 'src/app/services/background.service'; import { BackgroundService } from 'src/app/services/background.service';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page'; import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service' import { ThemeService } from 'src/app/services/theme.service'
import { DataService } from 'src/app/services/data.service'; import { DataService } from 'src/app/services/data.service';
+24 -9
View File
@@ -12,6 +12,8 @@ import { ChangeProfileService } from 'src/app/services/change-profile.service';
import { ThemeService } from 'src/app/services/theme.service'; import { ThemeService } from 'src/app/services/theme.service';
import { StorageService } from 'src/app/services/storage.service'; import { StorageService } from 'src/app/services/storage.service';
import { ChatService } from 'src/app/services/chat.service'; import { ChatService } from 'src/app/services/chat.service';
import { PermissionService } from 'src/app/services/permission.service';
import { PermissionList } from 'src/app/models/permissionList';
@Component({ @Component({
selector: 'app-login', selector: 'app-login',
@@ -29,7 +31,8 @@ export class LoginPage implements OnInit {
hasPin: boolean hasPin: boolean
loginPreference: string loginPreference: string
sessionStore = SessionStore sessionStore = SessionStore;
permissionList = new PermissionList();
constructor( constructor(
private notificatinsservice: NotificationsService, private notificatinsservice: NotificationsService,
@@ -40,7 +43,8 @@ export class LoginPage implements OnInit {
private clearStoreService: ClearStoreService, private clearStoreService: ClearStoreService,
private changeProfileService: ChangeProfileService, private changeProfileService: ChangeProfileService,
public ThemeService: ThemeService, public ThemeService: ThemeService,
private storageservice: StorageService private storageservice: StorageService,
public permissionService: PermissionService,
) {} ) {}
ngOnInit() { ngOnInit() {
@@ -101,26 +105,29 @@ export class LoginPage implements OnInit {
// login to API successfully // login to API successfully
if (attempt) { if (attempt) {
if (attempt.UserId == SessionStore.user.UserId) { if (attempt.UserId == SessionStore.user.UserId) {
await this.authService.SetSession(attempt, this.userattempt); await this.authService.SetSession(attempt, this.userattempt);
await this.authService.loginChat(); await this.authService.loginChat();
await this.authService.loginToChatWs() await this.authService.loginToChatWs();
this.getToken(); this.getToken();
SessionStore.setInativity(true); SessionStore.setInativity(true);
this.goback() this.goback();
} else { } else {
this.clearStoreService.clear() this.clearStoreService.clear();
SessionStore.delete() SessionStore.delete();
window.localStorage.clear(); window.localStorage.clear();
await this.authService.SetSession(attempt, this.userattempt); await this.authService.SetSession(attempt, this.userattempt);
this.changeProfileService.run() this.changeProfileService.run();
await this.authService.loginChat(); await this.authService.loginChat();
await this.authService.loginToChatWs() await this.authService.loginToChatWs();
this.getToken(); this.getToken();
this.router.navigateByUrl('/pin', { replaceUrl: true }); this.router.navigateByUrl('/pin', { replaceUrl: true });
} }
} }
else{ else{
@@ -141,7 +148,15 @@ export class LoginPage implements OnInit {
if(pathName) { if(pathName) {
this.router.navigate([pathName]); this.router.navigate([pathName]);
} else { } else {
this.router.navigate(['/home/events']); if(this.permissionService.userPermission(this.permissionList.Agenda) || this.permissionService.userPermission(this.permissionList.Gabinete)){
this.router.navigate(['/home/events']);
}
else if(this.permissionService.userPermission(this.permissionList.Chat)){
this.router.navigate(['/home/chat']);
}
else if(this.permissionService.userPermission(this.permissionList.Actions)){
this.router.navigate(['/home/publications']);
}
} }
} }
@@ -33,7 +33,9 @@
</ion-refresher> --> </ion-refresher> -->
<div class="main-container background-white height-100 overflow-y-auto"> <div class="main-container background-white height-100 overflow-y-auto">
<ion-content> <ion-content>
<ion-card *ngFor="let publication of getpublication let i = index"> <ion-card *ngFor="let publication of getpublication let i = index"
(click)="goToPublicationDetail(publication.DocumentId)"
>
<ion-card-content> <ion-card-content>
<div class="post-img"> <div class="post-img">
<img [lazyLoad]="publication.FileBase64"> <img [lazyLoad]="publication.FileBase64">
+13 -3
View File
@@ -18,6 +18,7 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { AttachmentsService } from 'src/app/services/attachments.service'; import { AttachmentsService } from 'src/app/services/attachments.service';
import { RoomService } from './chat/room.service'; import { RoomService } from './chat/room.service';
import { Storage } from '@ionic/storage'; import { Storage } from '@ionic/storage';
import { InitialsService } from './functions/initials.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -44,7 +45,8 @@ export class AuthService {
private NfService:NfService, private NfService:NfService,
private processesService: ProcessesService, private processesService: ProcessesService,
private AttachmentsService: AttachmentsService, private AttachmentsService: AttachmentsService,
private storage: Storage ) { private storage: Storage,
private initialsService: InitialsService ) {
this.headers = new HttpHeaders(); this.headers = new HttpHeaders();
@@ -74,6 +76,8 @@ export class AuthService {
try { try {
response = await this.http.post<LoginUserRespose>(environment.apiURL + "UserAuthentication/Login", '', this.opts).toPromise(); response = await this.http.post<LoginUserRespose>(environment.apiURL + "UserAuthentication/Login", '', this.opts).toPromise();
console.log(response);
if(saveSession) { if(saveSession) {
this.SetSession(response, user) this.SetSession(response, user)
} }
@@ -94,6 +98,9 @@ export class AuthService {
} else if(session.RoleID == 100000011) { } else if(session.RoleID == 100000011) {
session.Profile = 'MDGPR' session.Profile = 'MDGPR'
} }
else{
session.Profile = this.initialsService.getInitials(session.FullName);
}
session.Password = user.password session.Password = user.password
session.RochetChatUser = user.username.split('@')[0] session.RochetChatUser = user.username.split('@')[0]
@@ -124,7 +131,6 @@ export class AuthService {
let responseChat = await this.httpService.post('login', postData).toPromise(); let responseChat = await this.httpService.post('login', postData).toPromise();
if(responseChat) { if(responseChat) {
console.log('Login to Rocket chat OK', responseChat); console.log('Login to Rocket chat OK', responseChat);
this.ValidatedUserChat = responseChat; this.ValidatedUserChat = responseChat;
localStorage.setItem('userChat', JSON.stringify(responseChat)); localStorage.setItem('userChat', JSON.stringify(responseChat));
@@ -149,7 +155,7 @@ export class AuthService {
this.WsChatService.connect(); this.WsChatService.connect();
this.WsChatService.login().then((message: any) => { this.WsChatService.login().then((message: any) => {
SessionStore.user.RochetChatUserId = message.result.id SessionStore.user.RochetChatUserId = message.result.id
SessionStore.save() SessionStore.save()
this.WsChatService.setStatus('online') this.WsChatService.setStatus('online')
@@ -169,11 +175,15 @@ export class AuthService {
try { try {
let guid: any = await this.AttachmentsService.uploadFile(formData).toPromise() let guid: any = await this.AttachmentsService.uploadFile(formData).toPromise()
message.file.guid = guid.path message.file.guid = guid.path
console.log('========================================',guid)
// await this.storage.set(guid.path, message.file.image_url).then(() => { // await this.storage.set(guid.path, message.file.image_url).then(() => {
// console.log('add picture to chat IMAGE SAVED') // console.log('add picture to chat IMAGE SAVED')
// // message.getFileFromDb() // // message.getFileFromDb()
// }); // });
message.downloadFileMsg()
return true return true
} catch(e) { } catch(e) {
console.log('failed to upload to server', e) console.log('failed to upload to server', e)
+58 -40
View File
@@ -10,6 +10,8 @@ import { ChatStorageService } from './chat-storage.service'
import { ChatMethodsService } from './chat-methods.service' import { ChatMethodsService } from './chat-methods.service'
import { MessageModel, DeleteMessageModel } from '../../models/beast-orm' import { MessageModel, DeleteMessageModel } from '../../models/beast-orm'
import { AESEncrypt } from '../aesencrypt.service' import { AESEncrypt } from '../aesencrypt.service'
import { HttpClient, HttpEventType } from '@angular/common/http';
import { AttachmentsService } from 'src/app/services/attachments.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -22,10 +24,10 @@ export class MessageService {
msg = '' msg = ''
rid = '' rid = ''
ts = {} ts = {}
u = { u = {
name: '', name: '',
username: '', username: '',
_id: "" _id: ""
} }
@@ -59,7 +61,8 @@ export class MessageService {
private WsChatService: WsChatService, private WsChatService: WsChatService,
private ChatStorageService: ChatStorageService, private ChatStorageService: ChatStorageService,
private ChatMethodsService: ChatMethodsService, private ChatMethodsService: ChatMethodsService,
private AESEncrypt: AESEncrypt) { private AESEncrypt: AESEncrypt,
private AttachmentsService: AttachmentsService,) {
} }
setData({customFields = {}, channels, mentions, msg ,rid ,ts, u, t, _id, id, _updatedAt, file, attachments, temporaryData, localReference , viewed = [], received = [], delate = false, delateRequest =false, }:Message) { setData({customFields = {}, channels, mentions, msg ,rid ,ts, u, t, _id, id, _updatedAt, file, attachments, temporaryData, localReference , viewed = [], received = [], delate = false, delateRequest =false, }:Message) {
@@ -74,17 +77,21 @@ export class MessageService {
this._id = _id this._id = _id
this._updatedAt = _updatedAt || new Date().getTime() this._updatedAt = _updatedAt || new Date().getTime()
this.file = file this.file = file
this.attachments = attachments
this.temporaryData = temporaryData this.temporaryData = temporaryData
this.localReference = localReference || null this.localReference = localReference || null
this.id = id this.id = id
this.delate = delate this.delate = delate
this.delateRequest = delateRequest this.delateRequest = delateRequest
if(this.attachments?.length >= 1 && attachments?.length >= 1) {
this.attachments[0] = Object.assign(this.attachments[0], attachments[0])
} else {
this.attachments = attachments
}
this.viewed = [...new Set([...viewed,...this.viewed])]; this.viewed = [...new Set([...viewed,...this.viewed])];
this.received = [...new Set([...received,...this.received])]; this.received = [...new Set([...received,...this.received])];
if(!this.ts) { if(!this.ts) {
this.offline = true this.offline = true
this.messageSend = false this.messageSend = false
@@ -102,7 +109,6 @@ export class MessageService {
} }
if(this.hasFile) { if(this.hasFile) {
// this.getFileFromDb()
if(this.file.type != 'application/webtrix') { if(this.file.type != 'application/webtrix') {
this.displayType = this.file.type.replace('application/','').toUpperCase() this.displayType = this.file.type.replace('application/','').toUpperCase()
} }
@@ -118,19 +124,6 @@ export class MessageService {
return firstName + ' ' + lastName return firstName + ' ' + lastName
} }
// getFileFromDb() {
// if(this.hasFile) {
// if (this.file.guid) {
// this.storage.get(this.file.guid).then((image) => {
// if(image != null) {
// this.file.image_url = image
// }
// });
// }
// }
// }
async send(): Promise<any> { async send(): Promise<any> {
this.sendAttempt++; this.sendAttempt++;
@@ -138,7 +131,7 @@ export class MessageService {
if(!this.hasFile) { if(!this.hasFile) {
const params = {roomId:this.rid, msg:this.msg, localReference: this.localReference} const params = {roomId:this.rid, msg:this.msg, localReference: this.localReference}
await this.sendRequest(params) await this.sendRequest(params)
} else { } else {
@@ -152,7 +145,7 @@ export class MessageService {
this.uploadingFile = false this.uploadingFile = false
if(uploadSuccessfully || this.hasSendAttachment == false) { if(uploadSuccessfully) {
this.hasSendAttachment = true this.hasSendAttachment = true
this.errorUploadingAttachment = false this.errorUploadingAttachment = false
this.temporaryData = {} this.temporaryData = {}
@@ -178,7 +171,7 @@ export class MessageService {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
reject(false) reject(false)
}) })
} }
} }
@@ -186,6 +179,11 @@ export class MessageService {
} }
async sendRequest(params) { async sendRequest(params) {
if(params?.attachments?.image_url) {
delete params?.attachments?.image_url
}
this.ChatMethodsService.send(params).subscribe( this.ChatMethodsService.send(params).subscribe(
(response: any) => { (response: any) => {
const ChatMessage = response.message const ChatMessage = response.message
@@ -197,13 +195,8 @@ export class MessageService {
this.WsChatService.registerCallback({ this.WsChatService.registerCallback({
type: 'reConnect', type: 'reConnect',
funx: async ()=> { funx: async ()=> {
this.WsChatService.send(params).then(({message, requestId}) => { this.send()
let ChatMessage = message.result
this.messageSend = true
this.redefinedMessage(ChatMessage)
})
return true return true
} }
}) })
@@ -213,7 +206,7 @@ export class MessageService {
async redefinedMessage(ChatMessage , update = true) { async redefinedMessage(ChatMessage , update = true) {
ChatMessage = this.NfService.fix_updatedAt(ChatMessage) ChatMessage = this.NfService.fix_updatedAt(ChatMessage)
const message = this.getChatObj() const message = this.getChatObj()
ChatMessage = Object.assign(message, ChatMessage) ChatMessage = Object.assign(message, ChatMessage)
@@ -222,11 +215,36 @@ export class MessageService {
await this.save() await this.save()
} }
async downloadFileMsg() { downloadFileMsg() {
const result = await this.NfService.beforeSendAttachment(this)
if(result) {
} let downloadFile = "";
this.AttachmentsService.downloadFile(this.file.guid).subscribe(async (event) => {
if (event.type === HttpEventType.DownloadProgress) {
} else if (event.type === HttpEventType.Response) {
if (this.file.type == "application/img") {
downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
} else if (this.file.type === 'application/pdf') {
downloadFile = event.body as any;
} else if (this.file.type == 'application/audio') {
downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '');
}
this.attachments[0] = {
image_url: downloadFile,
name: this.attachments[0].name,
title: this.attachments[0].title,
title_link: downloadFile,
title_link_download: this.attachments[0].title_link_download,
ts: this.attachments[0].ts
}
// save the changes to the storage
this.save()
}
});
} }
@@ -241,8 +259,7 @@ export class MessageService {
} }
async delateDB() { async delateDB() {
// alert('delete data')
const message = await MessageModel.get({_id: this._id}) const message = await MessageModel.get({_id: this._id})
await message.delete() await message.delete()
@@ -261,8 +278,8 @@ export class MessageService {
return { return {
channels: this.channels, channels: this.channels,
mentions: this.mentions, mentions: this.mentions,
//msg: this.AESEncrypt.encrypt(this.msg, SessionStore.user.RochetChatUser), //msg: this.AESEncrypt.encrypt(this.msg, SessionStore.user.RochetChatUser),
msg:this.msg, msg:this.msg,
rid: this.rid, rid: this.rid,
ts: this.ts, ts: this.ts,
u: this.u, u: this.u,
@@ -294,6 +311,7 @@ export class MessageService {
async save() { async save() {
const message = this.getChatObj() const message = this.getChatObj()
console.log(message);
await MessageModel.update(message) await MessageModel.update(message)
+56 -39
View File
@@ -21,6 +21,7 @@ import { ChatMethodsService } from './chat-methods.service'
import { DeleteMessageModel, MessageModel } from '../../models/beast-orm' import { DeleteMessageModel, MessageModel } from '../../models/beast-orm'
import { AESEncrypt } from '../aesencrypt.service' import { AESEncrypt } from '../aesencrypt.service'
import { IncomingChatMessage, ChatMessageInterface, falseTypingMethod } from 'src/app/models/message.model'; import { IncomingChatMessage, ChatMessageInterface, falseTypingMethod } from 'src/app/models/message.model';
import { AttachmentsService } from 'src/app/services/attachments.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -75,7 +76,8 @@ export class RoomService {
private NfService: NfService, private NfService: NfService,
private ChatStorageService: ChatStorageService, private ChatStorageService: ChatStorageService,
private ChatMethodsService: ChatMethodsService, private ChatMethodsService: ChatMethodsService,
private AESEncrypt: AESEncrypt private AESEncrypt: AESEncrypt,
private AttachmentsService: AttachmentsService
) { ) {
this.NativeNotificationService.askForPermission() this.NativeNotificationService.askForPermission()
@@ -143,7 +145,7 @@ export class RoomService {
} }
} }
setData({members, u, customFields = {}, id, name, t, lastMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt), _updatedAt }) { setData({members, u, customFields = {}, id, name, t, lastMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService), _updatedAt }) {
this.customFields = customFields this.customFields = customFields
this.id = id this.id = id
this.name = name this.name = name
@@ -236,7 +238,6 @@ export class RoomService {
const args = message.fields.args const args = message.fields.args
// alert(JSON.stringify(args))
if (typeof args[1] != 'object') { if (typeof args[1] != 'object') {
@@ -269,7 +270,12 @@ export class RoomService {
getRoomMembersIds(): string[] { getRoomMembersIds(): string[] {
return this.members.map((user)=> user._id) try {
return this.members.map((user)=> user._id)
} catch(error) {
return []
}
} }
getAllMemberThatIsNotOffline(): string[] { getAllMemberThatIsNotOffline(): string[] {
@@ -357,37 +363,46 @@ export class RoomService {
* @description delete message in the view * @description delete message in the view
* @param id message ID * @param id message ID
*/ */
async deleteMessage(id) { async deleteMessage(_id) {
await this.messages.forEach(async(message, index) => {
if(message._id == id) { const id = _id
this.messages.splice(index, 1) for (let i =0; i <= this.messages.length; i++) {
if(this.messages[i]?._id == id ) {
if (SessionStore.user.RochetChatUser == message.u.username) { //Get previous last message from room
const previousLastMessage = this.messages.slice(-1)[0];
this.lastMessage = previousLastMessage;
this.calDateDuration(previousLastMessage._updatedAt)
this.sortRoomList()
if (SessionStore.user.RochetChatUser == this.messages[i]?.u?.username) {
const allMemberThatIsOffline = this.getAllMemberThatIsOffline() const allMemberThatIsOffline = this.getAllMemberThatIsOffline()
await DeleteMessageModel.create({ DeleteMessageModel.create({
messageId: message._id, messageId: this.messages[i]._id,
rid: message.rid, rid: this.messages[i].rid,
ts: message.ts, ts: this.messages[i].ts,
u: message.u, u: this.messages[i].u,
needToReceiveBy: allMemberThatIsOffline needToReceiveBy: allMemberThatIsOffline
}) })
} }
message.delateStatusFalse() this.messages[i]?.delateDB()
message.delateDB()
//Get previous last message from room // console.log(_id,'==',this.messages[i]?._id, true)
const previousLastMessage = this.messages.slice(-1)[0]; this.messages.splice(i, 1)
this.lastMessage = previousLastMessage; return true
this.calDateDuration(previousLastMessage._updatedAt)
this.sortRoomList()
} else {
// console.log(_id,'==',this.messages[i]?._id, false)
} }
}) }
} }
@@ -411,22 +426,26 @@ export class RoomService {
async sendDeleteRequest(msgId) { async sendDeleteRequest(msgId) {
const message = this.messages.find((e)=>e._id = msgId) const message = this.messages.find((e)=>e._id == msgId)
message.delateStatusFalse() await message.delateStatusFalse()
this.ChatMethodsService.deleteMessage({_id:msgId, msgId:msgId, roomId:message.rid}).subscribe( this.ChatMethodsService.deleteMessage({_id:msgId, msgId:msgId, roomId:message.rid}).subscribe(
(response: any) => { async (response: any) => {
message.delateRequest = true
message.save()
this.deleteMessage(msgId)
},
(response) => {
if (response.error.error.startsWith('No message found with the id of')) { message.delateRequest = true
// alert('not found') await message.save()
this.deleteMessage(msgId)
},
async (response) => {
if (response?.error?.error.startsWith('No message found with the id of')) {
this.deleteMessage(msgId) this.deleteMessage(msgId)
message.delateRequest = true
await message.save()
} else { } else {
// this.deleteMessage(DeletedMessageId)
this.WsChatService.registerCallback({ this.WsChatService.registerCallback({
type: 'reConnect', type: 'reConnect',
funx: async ()=> { funx: async ()=> {
@@ -666,7 +685,7 @@ export class RoomService {
message = this.fix_updatedAt(message) message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt) const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService)
wewMessage.setData(message) wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory wewMessage.loadHistory = this.hasLoadHistory
@@ -694,8 +713,6 @@ export class RoomService {
} }
async ChatMessageIsPresentInTheView(ChatMessage:ChatMessageInterface) { async ChatMessageIsPresentInTheView(ChatMessage:ChatMessageInterface) {
let foundIndex; let foundIndex;
@@ -725,7 +742,7 @@ export class RoomService {
async prepareCreate({message, save = true}): Promise<MessageService> { async prepareCreate({message, save = true}): Promise<MessageService> {
message = this.fix_updatedAt(message) message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt) const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService)
wewMessage.setData(message) wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory wewMessage.loadHistory = this.hasLoadHistory
@@ -737,7 +754,7 @@ export class RoomService {
simplePrepareMessage(message) { simplePrepareMessage(message) {
message = this.fix_updatedAt(message) message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt) const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService)
wewMessage.setData(message) wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory wewMessage.loadHistory = this.hasLoadHistory
@@ -19,6 +19,7 @@ import { AuthService } from '../auth.service';
import { ChatStorageService } from './chat-storage.service' import { ChatStorageService } from './chat-storage.service'
import { ChatMethodsService } from './chat-methods.service' import { ChatMethodsService } from './chat-methods.service'
import { AESEncrypt } from '../aesencrypt.service' import { AESEncrypt } from '../aesencrypt.service'
import { AttachmentsService } from 'src/app/services/attachments.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -55,7 +56,8 @@ export class WsChatMethodsService {
private authService: AuthService, private authService: AuthService,
private ChatStorageService: ChatStorageService, private ChatStorageService: ChatStorageService,
private ChatMethodsService:ChatMethodsService, private ChatMethodsService:ChatMethodsService,
private AESEncrypt: AESEncrypt private AESEncrypt: AESEncrypt,
private AttachmentsService:AttachmentsService
) { ) {
this.loggedUser = authService.ValidatedUserChat['data']; this.loggedUser = authService.ValidatedUserChat['data'];
@@ -158,7 +160,10 @@ export class WsChatMethodsService {
} catch(e){} } catch(e){}
this.sortRoomList() setTimeout(()=>{
this.sortRoomList()
}, 1000)
} }
async getAllRooms () { async getAllRooms () {
@@ -202,7 +207,11 @@ export class WsChatMethodsService {
console.log('save rooms', rooms) console.log('save rooms', rooms)
await this.storage.set('Rooms', rooms); await this.storage.set('Rooms', rooms);
this.sortRoomList()
setTimeout(()=>{
this.sortRoomList()
}, 1000)
this.loadingWholeList = false this.loadingWholeList = false
} }
@@ -305,7 +314,7 @@ export class WsChatMethodsService {
// create room // create room
if(!this.roomExist(roomId)) { if(!this.roomExist(roomId)) {
let room:RoomService = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService , this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt) let room:RoomService = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService , this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService)
room.setData(setData) room.setData(setData)
room.receiveMessage() room.receiveMessage()
room.getAllUsers = this.getUsers room.getAllUsers = this.getUsers
+1 -1
View File
@@ -728,7 +728,7 @@ export class WsChatService {
this.wsMsgQueue[requestId] = {message, requestId, loginRequired} this.wsMsgQueue[requestId] = {message, requestId, loginRequired}
} else { } else {
let messageStr = JSON.stringify(message) let messageStr = JSON.stringify(message)
console.log('messageStr', messageStr) // console.log('messageStr', messageStr)
this.socket.send(messageStr) this.socket.send(messageStr)
} }
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { InitialsService } from './initials.service';
describe('InitialsService', () => {
let service: InitialsService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(InitialsService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class InitialsService {
constructor() { }
getInitials(name:string){
let names = name.split(' '),
initials = names[0].substring(0, 1).toUpperCase();
if (names.length > 1) {
initials += names[names.length - 1].substring(0, 1).toUpperCase();
}
return initials;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { PermissionService } from './worker/permission.service'; import { PermissionService } from './permission.service';
describe('PermissionService', () => { describe('PermissionService', () => {
let service: PermissionService; let service: PermissionService;
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { SessionStore } from '../../store/session.service'; import { SessionStore } from '../store/session.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -15,12 +15,28 @@ export class PermissionService {
if(!Array.isArray(args)) { if(!Array.isArray(args)) {
args = [args] args = [args]
} }
return args.includes(this.SessionStore.user.Profile) return args.includes(this.SessionStore.user.Profile)
}
userPermission(args) {
if(!Array.isArray(args)) {
args = [args]
}
for(let permission of (this.SessionStore.user.UserPermissions || [])){
if (args.includes(permission)){
return true;
}
}
return false;
} }
role(args: any) { role(args: any) {
let UserRoleIsValid = this.userRole(args) let UserRoleIsValid = this.userRole(args)
return { return {
@@ -39,4 +55,4 @@ export class PermissionService {
} }
} }
+2 -2
View File
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AttachmentsService } from '../attachments.service'; import { AttachmentsService } from '../attachments.service';
import { EventsService } from '../events.service'; import { EventsService } from '../events.service';
import { PermissionService } from '../worker/permission.service'; import { PermissionService } from '../permission.service';
@@ -18,7 +18,7 @@ export class EventService {
create({body, calendar}) { create({body, calendar}) {
if(this.p.userRole(['PR'])) { if(this.p.userRole(['PR'])) {
return this.eventService.postEventPr(body, calendar) return this.eventService.postEventPr(body, calendar)
@@ -60,66 +60,75 @@
</div> </div>
</div> </div>
<div *ngIf="msg.file && msg.delate == false"> <div *ngIf="msg.file">
<div class="message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45" *ngIf="msg.t != 'r' && msg.t != 'ul' && msg.t != 'au' && msg.t != 'ru' && msg.file.type != 'application/meeting'" > <div class="message-item incoming-{{msg.u.username!=loggedUser.me.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 *ngIf="msg.file.type != 'application/meeting'">
<div class="message-item-options d-flex justify-content-end"> <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> <fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before"> <mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button> <button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
</mat-menu> </mat-menu>
</div> </div>
<div class="title"> <div class="title">
<ion-label>{{msg.u.name}}</ion-label> <ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span> <span class="time">{{msg.duration}}</span>
</div> </div>
<div class="message"> <div class="message">
<div *ngIf="msg.attachments" class="message-attachments"> <div *ngIf="msg.attachments" class="message-attachments">
<div *ngFor="let file of msg.attachments"> <div *ngFor="let file of msg.attachments">
<div *ngIf="msg.file.type == 'application/img'" (click)="openPreview(msg)"> <div *ngIf="msg.file.type == 'application/img' && !msg.attachments[0].image_url">
<img *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image"> NOT UPLOADED
<ion-icon *ngIf="msg.attachments[0].image_url == null" name="download-outline"></ion-icon> </div>
</div> <div *ngIf="msg.file.type == 'application/img' &&
<div *ngIf="msg.file.type != 'application/img'"> msg.attachments[0].image_url" (click)="openPreview(msg)">
<div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color"> <img *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image">
<div (click)="openPreview(msg)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file"> <ion-icon *ngIf="msg.attachments[0].image_url == null" name="download-outline"></ion-icon>
<span *ngIf="msg.file.type"> </div>
<fa-icon *ngIf="msg.file.type == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon> <div *ngIf="msg.file.type != 'application/img'">
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-icon"></fa-icon> <div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color">
<fa-icon *ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'" icon="file-word" class="excel-icon"></fa-icon> <div (click)="openPreview(msg)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-icon> <span *ngIf="msg.file.type">
</span> <fa-icon *ngIf="msg.file.type == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
<ion-label class="file-title">{{file.title}}</ion-label> <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.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>{{file.title}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></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>
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label>
</div> </div>
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'">
<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>
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label>
</div> </div>
</div> </div>
</div> </div>
{{last ? scrollToBottom() : ''}}
</div> </div>
{{last ? scrollToBottom() : ''}}
</div> </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.id)" 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>
<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.id)" 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 *ngIf="msg.file && msg.delate == true">
Apagou a mensagem
</div>
<div *ngIf="msg.t == 'r'" class="info-text"> <div *ngIf="msg.t == 'r'" class="info-text">
<ion-label>Alterou o nome do grupo para "{{msg.msg.split('-').join(' ')}}"</ion-label><br /> <ion-label>Alterou o nome do grupo para "{{msg.msg.split('-').join(' ')}}"</ion-label><br />
@@ -208,9 +217,9 @@
<ion-fab-button title="Nova Reunião" (click)="bookMeeting()" color="light"> <ion-fab-button title="Nova Reunião" (click)="bookMeeting()" color="light">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
</ion-fab-button> </ion-fab-button>
<ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light"> <!-- <ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light">
<ion-icon name="document"></ion-icon> <ion-icon name="document"></ion-icon>
</ion-fab-button> </ion-fab-button> -->
<ion-fab-button title="Anexar Fotografia" (click)="addImage()" color="light"> <ion-fab-button title="Anexar Fotografia" (click)="addImage()" color="light">
<ion-icon name="image"></ion-icon> <ion-icon name="image"></ion-icon>
</ion-fab-button> </ion-fab-button>
@@ -274,20 +274,23 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
} }
async loadFiles() { async loadFiles() {
try {
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if(recordData?.value?.recordDataBase64.includes('data:audio')){
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64);
}
else{
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`);
}
});
} catch (error) {}
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64);
}
else{
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`);
}
});
} }
startRecording() { startRecording() {
@@ -417,41 +420,64 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
this.wsChatMethodsService.getGroupRoom(this.roomId).send({}) this.wsChatMethodsService.getGroupRoom(this.roomId).send({})
} }
async sendAudio(fileName) { base64toBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
async sendAudio(fileName) {
const roomId = this.roomId const roomId = this.roomId
let audioFile;
this.storage.get('recordData').then((recordData) => { this.storage.get('recordData').then((recordData) => {
console.log(recordData); console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){ audioFile = recordData;
this.audioRecorded = recordData.value.recordDataBase64; if(recordData?.value?.recordDataBase64.includes('data:audio')){
this.audioRecorded = recordData?.value?.recordDataBase64;
} }
else{ else{
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`;
} }
});
//Converting base64 to blob //Converting base64 to blob
const base64Response = await fetch(this.audioRecorded); const encodedData = btoa(this.audioRecorded);
const blob = await base64Response.blob(); const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
console.log(blob)
const formData = new FormData(); const formData = new FormData();
formData.append("blobFile", blob); formData.append("blobFile", blob);
this.wsChatMethodsService.getGroupRoom(roomId).send({ this.wsChatMethodsService.getGroupRoom(roomId).send({
file: { file: {
"type": "application/audio", "type": "application/audio",
/* "guid": '', */ "msDuration":audioFile.value.msDuration,
"mimeType":audioFile.value.mimeType,
}, },
attachments: [{ attachments: [{
"title": fileName , "title": fileName ,
"title_link": this.audioRecorded,
"title_link_download": true, "title_link_download": true,
"type": "file" "type": "audio"
}], }],
temporaryData: formData temporaryData: formData
}) })
this.deleteRecording();
});
this.deleteRecording();
} }
deleteMessage(msgId: string) { deleteMessage(msgId: string) {
@@ -971,41 +997,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
downloadFileMsg(msg: MessageService) { downloadFileMsg(msg: MessageService) {
console.log('FILE TYPE', msg.file.type) msg.downloadFileMsg()
this.downloadFile = "";
if (msg.file.type == "application/img") {
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
console.log('FILE TYPE 22', msg.file.guid)
var name = msg.file.guid;
if (event.type === HttpEventType.DownloadProgress) {
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
console.log('FILE TYPE 33', msg.file.type)
} else if (event.type === HttpEventType.Response) {
if (msg.file.type == "application/img") {
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
} else if (msg.file.type === 'application/pdf') {
this.downloadFile = event.body;
}
msg.attachments[0] = {
image_url: this.downloadFile,
name: msg.attachments[0].name,
title: msg.attachments[0].title,
title_link_download: msg.attachments[0].title_link_download,
ts: msg.attachments[0].ts
}
await this.storage.set(msg.file.guid, this.downloadFile).then(() => {
console.log('IMAGE SAVED')
});
}
});
}
} }
async openPreview(msg) { async openPreview(msg) {
@@ -1029,5 +1021,12 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
} }
async audioPreview(msg) {
console.log(msg);
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
this.downloadFileMsg(msg)
} else {}
}
} }
+27 -18
View File
@@ -35,7 +35,7 @@
</ion-refresher> </ion-refresher>
<div class="messages" #scrollMe> <div class="messages" #scrollMe>
<div class="messages-list-item-wrapper container-width-100" <div class="messages-list-item-wrapper container-width-100"
*ngFor="let msg of wsChatMethodsService.getDmRoom(roomId).messages; let last = last"> *ngFor="let msg of wsChatMethodsService.getDmRoom(roomId).messages; index as i; let last = last">
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45' *ngIf="msg.msg !=''"> <div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45' *ngIf="msg.msg !=''">
<div class="message-item-options d-flex justify-content-end"> <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 [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer">
@@ -49,12 +49,12 @@
<span class="time">{{msg.duration}}</span> <span class="time">{{msg.duration}}</span>
</div> </div>
<div class="d-flex justify-space-between"> <div class="d-flex justify-space-between">
<ion-label *ngIf="msg.delate == false" class="flex-0">{{msg.msg}}</ion-label> <ion-label *ngIf="msg.delate == false" class="flex-0">{{msg.msg}} </ion-label>
<ion-label *ngIf="msg.delate == true" class="flex-0">Apagou a mensagem</ion-label> <ion-label *ngIf="msg.delate == true" class="flex-0">Apagou a mensagem</ion-label>
<ion-label class="float-status-all float-status" > <ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == true && msg.received.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.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
@@ -84,7 +84,6 @@
<div *ngIf="msg.file.type == 'application/img'" (click)="openPreview(msg)" dfsdvsvs> <div *ngIf="msg.file.type == 'application/img'" (click)="openPreview(msg)" dfsdvsvs>
<img src={{msg.attachments[0].image_url}} alt="image"> <img src={{msg.attachments[0].image_url}} alt="image">
<ion-label class="float-status-all float-status" > <ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == true && msg.received.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.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
@@ -109,7 +108,15 @@
<ion-label class="file-title">{{file.title}}</ion-label> <ion-label class="file-title">{{file.title}}</ion-label>
</div> </div>
</div> </div>
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'"> <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>{{file.title}}</ion-label>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></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" class="flex-grow-1" controls controlsList="nodownload noplaybackrate"></audio> <audio [src]="file.title_link|safehtml" preload="metadata" class="flex-grow-1" controls controlsList="nodownload noplaybackrate"></audio>
</div> </div>
<div class="file-details-optional add-attachment-bg-color"> <div class="file-details-optional add-attachment-bg-color">
@@ -119,7 +126,7 @@
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span> <span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label> </ion-label>
<ion-label class="float-status-all float-status" > <ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon> <ion-icon *ngIf="msg.messageSend == true && msg.received.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.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
@@ -133,28 +140,30 @@
</div> </div>
</div> </div>
<div class="info-meeting" *ngIf="msg.file.type == 'application/meeting'"> <div class="info-meeting" *ngIf="msg.file.type == 'application/meeting'">
<ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal"> <ion-label *ngIf="msg.delate == true" class="info-meeting-small">Apagou a mensagem</ion-label><br />
<ion-label *ngIf="msg.delate == false" class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button *ngIf="msg.delate == false" (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal">
<ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label> <ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label>
</button><br /> </button><br />
<ion-label class="info-meeting-medium"> <ion-label *ngIf="msg.delate == false" class="info-meeting-medium">
<ion-icon name="calendar-outline"></ion-icon> De {{showDateDuration(msg.file.start_date)}} a <ion-icon name="calendar-outline"></ion-icon> De {{showDateDuration(msg.file.start_date)}} a
{{showDateDuration(msg.file.end_date)}} {{showDateDuration(msg.file.end_date)}}
</ion-label><br /> </ion-label><br />
<ion-label class="info-meeting-medium"> <ion-label *ngIf="msg.delate == false" class="info-meeting-medium">
<ion-icon></ion-icon> <ion-icon></ion-icon>
<ion-icon name="location-outline"></ion-icon> {{msg.file.venue}} <ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}
</ion-label><br /> </ion-label><br />
</div> </div>
</div> </div>
<div *ngIf="msg.file && msg.delate == true">
Apagou a mensagem
</div>
</div> </div>
</div> </div>
<ion-fab horizontal="end" vertical="bottom" slot="fixed"> <ion-fab horizontal="end" vertical="bottom" slot="fixed">
<ion-fab-button *ngIf="scrollToBottomBtn" (click)="scrollToBottomClicked()" color="light" size="small"> <ion-fab-button *ngIf="scrollToBottomBtn" (click)="scrollToBottomClicked()" color="light" size="small">
<ion-icon name="chevron-down"></ion-icon> <ion-icon name="chevron-down"></ion-icon>
@@ -165,7 +174,7 @@
<ion-footer (click)="wsChatMethodsService.getDmRoom(roomId).sendReadMessage()"> <ion-footer (click)="wsChatMethodsService.getDmRoom(roomId).sendReadMessage()">
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true" > <div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true" >
<ngx-letters-avatar *ngIf="showAvatar" <ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "wsChatMethodsService.getDmRoom(roomId).name" [avatarName]= "wsChatMethodsService.getDmRoom(roomId).name"
@@ -189,9 +198,9 @@
<ion-fab-button title="Nova Reunião" (click)="bookMeeting()" color="light"> <ion-fab-button title="Nova Reunião" (click)="bookMeeting()" color="light">
<ion-icon name="calendar"></ion-icon> <ion-icon name="calendar"></ion-icon>
</ion-fab-button> </ion-fab-button>
<ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light"> <!-- <ion-fab-button title="Adicionar Documento" (click)="addFile()" color="light">
<ion-icon name="document"></ion-icon> <ion-icon name="document"></ion-icon>
</ion-fab-button> </ion-fab-button> -->
<ion-fab-button title="Anexar Fotografia" (click)="addImage()" color="light"> <ion-fab-button title="Anexar Fotografia" (click)="addImage()" color="light">
<ion-icon name="image"></ion-icon> <ion-icon name="image"></ion-icon>
</ion-fab-button> </ion-fab-button>
@@ -227,6 +227,13 @@
margin-top: 4px; margin-top: 4px;
} }
.chat-icon-download{
font-size: 95px;
margin: 0 auto;
margin-top: 4px;
border: 1px solid red;
}
.type-message{ .type-message{
display: flex; display: flex;
border: 1px solid #ebebeb; border: 1px solid #ebebeb;
@@ -329,3 +336,8 @@ display: block;
.typing ngx-letters-avatar { .typing ngx-letters-avatar {
padding-right: 5px; padding-right: 5px;
} }
.div-do-audio{
border: 1px solid red !important;
overflow: auto;
}
+65 -63
View File
@@ -25,7 +25,6 @@ import { WsChatMethodsService } from 'src/app/services/chat/ws-chat-methods.serv
import { WsChatService } from 'src/app/services/chat/ws-chat.service' import { WsChatService } from 'src/app/services/chat/ws-chat.service'
import { MessageService } from 'src/app/services/chat/message.service'; import { MessageService } from 'src/app/services/chat/message.service';
import { AttachmentsService } from 'src/app/services/attachments.service'; import { AttachmentsService } from 'src/app/services/attachments.service';
import { CameraService } from 'src/app/services/camera.service'; import { CameraService } from 'src/app/services/camera.service';
import { FileType } from 'src/app/models/fileType'; import { FileType } from 'src/app/models/fileType';
import { SearchPage } from 'src/app/pages/search/search.page'; import { SearchPage } from 'src/app/pages/search/search.page';
@@ -250,10 +249,22 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
} }
async loadFiles() { async loadFiles() {
try {
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if (recordData?.value?.recordDataBase64.includes('data:audio')) {
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64);
}
else {
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`);
}
});
} catch (error) { }
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => { this.storage.get('recordData').then((recordData) => {
console.log(recordData); console.log(recordData);
@@ -267,7 +278,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
} }
startRecording() { startRecording() {
console.log('Recording');
if (this.recording) { if (this.recording) {
return; return;
@@ -354,64 +364,49 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.wsChatMethodsService.getDmRoom(this.roomId).send({}) this.wsChatMethodsService.getDmRoom(this.roomId).send({})
} }
async sendAudio(fileName) {
async sendAudio(fileName) {
const roomId = this.roomId const roomId = this.roomId
let audioFile; let audioFile;
this.storage.get('recordData').then((recordData) => { this.storage.get('recordData').then((recordData) => {
console.log(recordData); console.log(recordData);
audioFile = recordData; audioFile = recordData;
if (recordData.value.recordDataBase64.includes('data:audio')) { if (recordData.value.recordDataBase64.includes('data:audio')) {
this.audioRecorded = recordData.value.recordDataBase64; this.audioRecorded = recordData.value.recordDataBase64;
} }
else { else{
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`;
} }
}); //Converting base64 to blob
const encodedData = btoa(this.audioRecorded);
const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
console.log(blob)
const formData = new FormData();
formData.append("blobFile", blob);
//Converting base64 to blob this.wsChatMethodsService.getDmRoom(roomId).send({
const base64Response = await fetch(this.audioRecorded); file: {
const blob = await base64Response.blob(); "type": "application/audio",
"msDuration": audioFile.value.msDuration,
"mimeType": audioFile.value.mimeType,
},
attachments: [{
"title": fileName,
"title_link_download": true,
"type": "audio"
}],
temporaryData: formData
})
const formData = new FormData(); });
formData.append("blobFile", blob);
this.wsChatMethodsService.getDmRoom(roomId).send({
file: {
"type": "application/audio",
/* "guid": '', */
"msDuration": audioFile.value.msDuration,
"mimeType": audioFile.value.mimeType,
},
attachments: [{
"title": fileName,
"title_link": this.audioRecorded,
"title_link_download": true,
"type": "audio"
}],
temporaryData: formData
})
this.deleteRecording(); this.deleteRecording();
} }
deleteMessage(msgId: string, msg: MessageService) { deleteMessage(msgId: string, msg: MessageService) {
this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId)
/* msg.delateStatusFalse() if (msg.file.type == "application/webtrix") {
this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId) */
}
async viewDocument(msg: any, url?: string) {
if (msg.file.type == "application/img") {
let response: any = await this.AttachmentsService.getFile(msg.file.guid).toPromise();
console.log(response);
alert(response);
//this.openPreview(msg);
}
else if (msg.file.type == "application/webtrix") {
this.openViewDocumentModal(msg.file); this.openViewDocumentModal(msg.file);
} }
else { else {
@@ -955,6 +950,13 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
DocumentViewer.viewDocument DocumentViewer.viewDocument
} }
async audioPreview(msg) {
console.log(msg);
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
this.downloadFileMsg(msg)
} else { }
}
async openPreview(msg) { async openPreview(msg) {
console.log(msg); console.log(msg);
@@ -962,22 +964,22 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.downloadFileMsg(msg) this.downloadFileMsg(msg)
/* } else if (msg.file.type === "application/pdf") { /* } else if (msg.file.type === "application/pdf") {
console.log(str); console.log(str);
const win = window.open("", "_blank"); const win = window.open("", "_blank");
let html = ''; let html = '';
html += '<html>'; html += '<html>';
html += '<body style="margin:0!important">'; html += '<body style="margin:0!important">';
html += '<iframe width="100%" height="100%" src="' + str + '" type="application/pdf" />'; html += '<iframe width="100%" height="100%" src="' + str + '" type="application/pdf" />';
html += '</body>'; html += '</body>';
html += '</html>'; html += '</html>';
setTimeout(() => { setTimeout(() => {
win.document.write(html); win.document.write(html);
}, 0); */ }, 0); */
+5 -5
View File
@@ -66,7 +66,7 @@
<div class="d-flex flex-1 pr-20 pl-50"> <div class="d-flex flex-1 pr-20 pl-50">
<div class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/events')" <div *ngIf="p.userPermission([permissionList.Agenda]) || p.userPermission([permissionList.Gabinete])" class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/events')"
[class.active]="locationPathname() == '/home/events'"> [class.active]="locationPathname() == '/home/events'">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-home-active-black.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-home-active-black.svg'></ion-icon>
@@ -76,7 +76,7 @@
<span>Início</span> <span>Início</span>
</div> </div>
<div class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/agenda')" <div *ngIf="p.userPermission([permissionList.Agenda])" class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/agenda')"
[class.active]="locationPathname() == '/home/agenda'"> [class.active]="locationPathname() == '/home/agenda'">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-agenda-inactive.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-agenda-inactive.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-agenda-inactive.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-agenda-inactive.svg'></ion-icon>
@@ -85,7 +85,7 @@
<span>Agenda</span> <span>Agenda</span>
</div> </div>
<div class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/gabinete-digital')" <div *ngIf="p.userPermission([permissionList.Gabinete])" class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/gabinete-digital')"
[class.active]="locationPathname() == '/home/gabinete-digital'"> [class.active]="locationPathname() == '/home/gabinete-digital'">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-home-dk.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-home-dk.svg'></ion-icon>
@@ -94,7 +94,7 @@
<span>Gabinete</span> <span>Gabinete</span>
</div> </div>
<div class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/publications')" <div *ngIf="p.userPermission([permissionList.Actions])" class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/publications')"
[class.active]="locationPathname() == '/home/publications'"> [class.active]="locationPathname() == '/home/publications'">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-a-es-inactive.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-a-es-inactive.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-a-es-inactive.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-a-es-inactive.svg'></ion-icon>
@@ -102,7 +102,7 @@
<span>Acções</span> <span>Acções</span>
</div> </div>
<div class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/chat')" <div *ngIf="p.userPermission([permissionList.Chat])" class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/chat')"
[class.active]="locationPathname() == '/home/chat'"> [class.active]="locationPathname() == '/home/chat'">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-grupos-inactive-dk-white.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-40" src='assets/images/icons-nav-grupos-inactive-dk-white.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-grupos-inactive-dk-white.svg'></ion-icon> <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40" src='assets/images/theme/gov/icons-nav-grupos-inactive-dk-white.svg'></ion-icon>
+5 -2
View File
@@ -6,12 +6,13 @@ import { LoginUserRespose } from 'src/app/models/user.model';
import { ProfilePage } from 'src/app/modals/profile/profile.page'; import { ProfilePage } from 'src/app/modals/profile/profile.page';
import { StorageService } from '../../services/storage.service'; import { StorageService } from '../../services/storage.service';
import { SessionStore } from 'src/app/store/session.service'; import { SessionStore } from 'src/app/store/session.service';
//import { NotificationsService } from '../../services/notifications.service';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { EventTrigger } from '../../services/eventTrigger.service'; import { EventTrigger } from '../../services/eventTrigger.service';
import { ThemeService } from '../../services/theme.service'; import { ThemeService } from '../../services/theme.service';
import { interval } from 'rxjs'; import { interval } from 'rxjs';
import { RouteService } from 'src/app/services/route.service'; import { RouteService } from 'src/app/services/route.service';
import { PermissionList } from 'src/app/models/permissionList';
import { PermissionService } from 'src/app/services/permission.service';
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
@@ -29,6 +30,7 @@ export class HeaderPage implements OnInit {
notificationLength: 0; notificationLength: 0;
SessionStore = SessionStore SessionStore = SessionStore
check: boolean; check: boolean;
permissionList = new PermissionList();
production = environment.production production = environment.production
@@ -41,7 +43,8 @@ export class HeaderPage implements OnInit {
//private notificationsService: NotificationsService, //private notificationsService: NotificationsService,
private eventrigger: EventTrigger, private eventrigger: EventTrigger,
public ThemeService: ThemeService, public ThemeService: ThemeService,
public RouteService: RouteService public RouteService: RouteService,
public p: PermissionService,
) { ) {
this.loggeduser = SessionStore.user; this.loggeduser = SessionStore.user;
router.events.subscribe((val) => { router.events.subscribe((val) => {
@@ -7,7 +7,7 @@
</div> </div>
<div class="buttons"> <div class="buttons">
<button (click)="takePicture()" full class="btn-ok" shape="round" >Tirar Fotografia</button> <button (click)="takePicture()" full class="btn-ok" shape="round" >Tirar Fotografia</button>
<button (click)="addFile()" class="btn-ok" shape="round" >Anexar Documento</button> <!-- <button (click)="addFile()" class="btn-ok" shape="round" >Anexar Documento</button> -->
<button (click)="anexarFoto()" full class="btn-ok" shape="round" >Anexar Fotografia</button> <button (click)="anexarFoto()" full class="btn-ok" shape="round" >Anexar Fotografia</button>
<button (click)="addDocGestaoDocumental()" class="btn-ok" shape="round" >Gestão Documental</button> <button (click)="addDocGestaoDocumental()" class="btn-ok" shape="round" >Gestão Documental</button>
<div class="solid"></div> <div class="solid"></div>
@@ -9,7 +9,7 @@ import { BookMeetingModalPage } from 'src/app/pages/gabinete-digital/expediente/
import { DiscartExpedientModalPage } from 'src/app/pages/gabinete-digital/discart-expedient-modal/discart-expedient-modal.page'; import { DiscartExpedientModalPage } from 'src/app/pages/gabinete-digital/discart-expedient-modal/discart-expedient-modal.page';
import { ToastService } from 'src/app/services/toast.service'; import { ToastService } from 'src/app/services/toast.service';
import { customTask, fullTask } from 'src/app/models/dailyworktask.model'; import { customTask, fullTask } from 'src/app/models/dailyworktask.model';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ThemeService } from 'src/app/services/theme.service' import { ThemeService } from 'src/app/services/theme.service'
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { RouteService } from 'src/app/services/route.service'; import { RouteService } from 'src/app/services/route.service';
@@ -35,7 +35,7 @@ export class DespachosOptionsPage implements OnInit {
public p: PermissionService, public p: PermissionService,
public ThemeService: ThemeService, public ThemeService: ThemeService,
private RouteService: RouteService, private RouteService: RouteService,
) { ) {
this.task = this.navParams.get('task') this.task = this.navParams.get('task')
this.fulltask = this.navParams.get('fulltask') this.fulltask = this.navParams.get('fulltask')
@@ -84,7 +84,7 @@ export class DespachosOptionsPage implements OnInit {
this.toastService._badRequest('Processo não encontrado') this.toastService._badRequest('Processo não encontrado')
}); });
} }
async distartExpedientModal(){ async distartExpedientModal(){
this.popoverController.dismiss(); this.popoverController.dismiss();
console.log(this.fulltask); console.log(this.fulltask);
@@ -98,7 +98,7 @@ export class DespachosOptionsPage implements OnInit {
cssClass: 'discart-expedient-modal', cssClass: 'discart-expedient-modal',
backdropDismiss: false backdropDismiss: false
}); });
await modal.present(); await modal.present();
modal.onDidDismiss().then(res=>{ modal.onDidDismiss().then(res=>{
if(res['data']=='close'){ if(res['data']=='close'){
@@ -127,7 +127,7 @@ export class DespachosOptionsPage implements OnInit {
await modal.present(); await modal.present();
modal.onDidDismiss(); modal.onDidDismiss();
} }
async openDelegarModal(task: any) { async openDelegarModal(task: any) {
this.popoverController.dismiss(); this.popoverController.dismiss();
let classs; let classs;
@@ -157,8 +157,8 @@ export class DespachosOptionsPage implements OnInit {
} }
async generateDiploma(note:string, documents:any){ async generateDiploma(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Reencaminhar", "action": "Reencaminhar",
"ActionTypeId": 99999839, "ActionTypeId": 99999839,
"dataFields": { "dataFields": {
@@ -198,20 +198,20 @@ export class DespachosOptionsPage implements OnInit {
cssClass: classs, cssClass: classs,
backdropDismiss: true backdropDismiss: true
}); });
await modal.present(); await modal.present();
modal.onDidDismiss().then(async (res) => { modal.onDidDismiss().then(async (res) => {
console.log(res); console.log(res);
if(res.data) { if(res.data) {
const DocumentToSave = res.data.documents.map((e) => { const DocumentToSave = res.data.documents.map((e) => {
return { return {
ApplicationId: e.ApplicationType, ApplicationId: e.ApplicationType,
SourceId: e.Id, SourceId: e.Id,
} }
}); });
let docs = { let docs = {
ProcessInstanceID: "", ProcessInstanceID: "",
Attachments: DocumentToSave, Attachments: DocumentToSave,
@@ -235,11 +235,11 @@ export class DespachosOptionsPage implements OnInit {
this.goBack(); this.goBack();
} }
}); });
} }
async arquivar(note:string, documents:any) { async arquivar(note:string, documents:any) {
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Arquivo", "action": "Arquivo",
"ActionTypeId": 95, "ActionTypeId": 95,
"dataFields": { "dataFields": {
@@ -259,14 +259,14 @@ export class DespachosOptionsPage implements OnInit {
} finally { } finally {
loader.remove() loader.remove()
} }
} }
async executado(note:string, documents:any){ async executado(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Conhecimento", "action": "Conhecimento",
"ActionTypeId": 104, "ActionTypeId": 104,
"dataFields": { "dataFields": {
@@ -290,10 +290,10 @@ export class DespachosOptionsPage implements OnInit {
} }
async reexecutar(note:string, documents:any){ async reexecutar(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Reexecutar", "action": "Reexecutar",
"ActionTypeId": 100000010, "ActionTypeId": 100000010,
"dataFields": { "dataFields": {
@@ -9,7 +9,7 @@ import { BookMeetingModalPage } from 'src/app/pages/gabinete-digital/expediente/
import { DiscartExpedientModalPage } from 'src/app/pages/gabinete-digital/discart-expedient-modal/discart-expedient-modal.page'; import { DiscartExpedientModalPage } from 'src/app/pages/gabinete-digital/discart-expedient-modal/discart-expedient-modal.page';
import { ToastService } from 'src/app/services/toast.service'; import { ToastService } from 'src/app/services/toast.service';
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ThemeService } from 'src/app/services/theme.service' import { ThemeService } from 'src/app/services/theme.service'
import { RouteService } from 'src/app/services/route.service'; import { RouteService } from 'src/app/services/route.service';
@@ -36,11 +36,11 @@ export class DespachosPrOptionsPage implements OnInit {
private RouteService: RouteService, private RouteService: RouteService,
public p: PermissionService, public p: PermissionService,
public ThemeService: ThemeService, public ThemeService: ThemeService,
) { } ) { }
ngOnInit() { ngOnInit() {
this.profile = "mdgpr"; this.profile = "mdgpr";
this.activatedRoute.queryParams.subscribe(params => { this.activatedRoute.queryParams.subscribe(params => {
@@ -86,7 +86,7 @@ export class DespachosPrOptionsPage implements OnInit {
console.log(res['data']); console.log(res['data']);
if(res['data']=='openDiscart') { if(res['data']=='openDiscart') {
console.log('open discart'); console.log('open discart');
this.distartExpedientModal(); this.distartExpedientModal();
} else { } else {
@@ -108,7 +108,7 @@ export class DespachosPrOptionsPage implements OnInit {
this.toastService._badRequest('Processo não encontrado') this.toastService._badRequest('Processo não encontrado')
}); });
} }
async distartExpedientModal() { async distartExpedientModal() {
this.popoverController.dismiss(); this.popoverController.dismiss();
console.log(this.fulltask); console.log(this.fulltask);
@@ -122,7 +122,7 @@ export class DespachosPrOptionsPage implements OnInit {
cssClass: 'discart-expedient-modal', cssClass: 'discart-expedient-modal',
backdropDismiss: false backdropDismiss: false
}); });
await modal.present(); await modal.present();
modal.onDidDismiss().then(res=>{ modal.onDidDismiss().then(res=>{
if(res['data']=='close'){ if(res['data']=='close'){
@@ -132,7 +132,7 @@ export class DespachosPrOptionsPage implements OnInit {
this.openMenu(); */ this.openMenu(); */
} }
this.popoverController.dismiss('close') this.popoverController.dismiss('close')
}); });
} }
@@ -157,7 +157,7 @@ export class DespachosPrOptionsPage implements OnInit {
modal.onDidDismiss() modal.onDidDismiss()
} }
async openDelegarModal(task: any) { async openDelegarModal(task: any) {
this.popoverController.dismiss(); this.popoverController.dismiss();
let classs; let classs;
@@ -187,8 +187,8 @@ export class DespachosPrOptionsPage implements OnInit {
} }
async generateDiploma(note:string, documents:any) { async generateDiploma(note:string, documents:any) {
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Reencaminhar", "action": "Reencaminhar",
"ActionTypeId": 99999839, "ActionTypeId": 99999839,
"dataFields": { "dataFields": {
@@ -227,22 +227,22 @@ export class DespachosPrOptionsPage implements OnInit {
cssClass: classs, cssClass: classs,
backdropDismiss: true backdropDismiss: true
}); });
await modal.present(); await modal.present();
modal.onDidDismiss().then(async (res) => { modal.onDidDismiss().then(async (res) => {
console.log(res); console.log(res);
if(res.data){ if(res.data){
const DocumentToSave = res.data.documents.map((e) => { const DocumentToSave = res.data.documents.map((e) => {
return { return {
ApplicationId: e.ApplicationType, ApplicationId: e.ApplicationType,
SourceId: e.Id, SourceId: e.Id,
} }
}); });
let docs = { let docs = {
ProcessInstanceID: "", ProcessInstanceID: "",
Attachments: DocumentToSave, Attachments: DocumentToSave,
@@ -259,15 +259,15 @@ export class DespachosPrOptionsPage implements OnInit {
} }
else if(actionName == 'Reexecução') { else if(actionName == 'Reexecução') {
await this.reexecutar(res.data.note, docs); await this.reexecutar(res.data.note, docs);
} }
else if(actionName == 'Concluido') { else if(actionName == 'Concluido') {
await this.concluir(res.data.note, docs); await this.concluir(res.data.note, docs);
} }
this.goBack(); this.goBack();
} }
}); });
} }
async concluir(note:string, documents:any){ async concluir(note:string, documents:any){
@@ -297,8 +297,8 @@ export class DespachosPrOptionsPage implements OnInit {
} }
async arquivar(note:string, documents:any){ async arquivar(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Arquivo", "action": "Arquivo",
"ActionTypeId": 95, "ActionTypeId": 95,
"dataFields": { "dataFields": {
@@ -323,8 +323,8 @@ export class DespachosPrOptionsPage implements OnInit {
async executado(note:string, documents:any){ async executado(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Conhecimento", "action": "Conhecimento",
"ActionTypeId": 104, "ActionTypeId": 104,
"dataFields": { "dataFields": {
@@ -347,10 +347,10 @@ export class DespachosPrOptionsPage implements OnInit {
} }
async reexecutar(note:string, documents:any){ async reexecutar(note:string, documents:any){
let body = { let body = {
"serialNumber": this.serialNumber, "serialNumber": this.serialNumber,
"action": "Reexecutar", "action": "Reexecutar",
"ActionTypeId": 100000010, "ActionTypeId": 100000010,
"dataFields": { "dataFields": {
@@ -7,7 +7,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { TaskService } from 'src/app/Rules/task.service' import { TaskService } from 'src/app/Rules/task.service'
import { ExpedienteService } from 'src/app/Rules/expediente.service'; import { ExpedienteService } from 'src/app/Rules/expediente.service';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
@Component({ @Component({
selector: 'app-event-details-documents-options', selector: 'app-event-details-documents-options',
@@ -15,7 +15,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { TaskService } from 'src/app/Rules/task.service' import { TaskService } from 'src/app/Rules/task.service'
import { ExpedienteService } from 'src/app/Rules/expediente.service'; import { ExpedienteService } from 'src/app/Rules/expediente.service';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { ThemeService } from 'src/app/services/theme.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/pages/chat/new-group/new-group.page';
import { RouteService } from 'src/app/services/route.service'; import { RouteService } from 'src/app/services/route.service';
@@ -9,7 +9,7 @@ import { BookMeetingModalPage } from 'src/app/pages/gabinete-digital/expediente/
import { ProcessesService } from 'src/app/services/processes.service'; import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service'; import { ToastService } from 'src/app/services/toast.service';
import { PedidoService } from 'src/app/Rules/pedido.service'; import { PedidoService } from 'src/app/Rules/pedido.service';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
import { DataService } from 'src/app/services/data.service'; import { DataService } from 'src/app/services/data.service';
import { NewGroupPage } from 'src/app/pages/chat/new-group/new-group.page'; import { NewGroupPage } from 'src/app/pages/chat/new-group/new-group.page';
@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {PopoverController } from '@ionic/angular'; import {PopoverController } from '@ionic/angular';
import { PermissionService } from 'src/app/services/worker/permission.service'; import { PermissionService } from 'src/app/services/permission.service';
@Component({ @Component({
selector: 'app-searched-document-options', selector: 'app-searched-document-options',
@@ -0,0 +1,18 @@
<svg width="55" height="55" viewBox="0 0 55 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_223_29)">
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
</g>
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4327 31.208H20.3764C20.6649 31.208 20.9402 31.3245 21.1401 31.532L23.3285 33.7963C23.5285 34.0028 23.8037 34.1198 24.0923 34.1198H31.0456C31.3336 34.1198 31.6094 34.0033 31.8094 33.7963L33.9972 31.532C34.1972 31.325 34.473 31.208 34.7609 31.208H37.5879C38.1734 31.208 38.6487 31.6818 38.6487 32.2668V35.9727C38.6487 36.5577 38.1734 37.0315 37.5879 37.0315H17.4333C16.8472 37.0315 16.3725 36.5577 16.3725 35.9727V32.2668C16.3725 31.6818 16.8472 31.208 17.4333 31.208H17.4327ZM29.6316 19.0358V26.1214L30.8186 26.087C31.1114 26.0785 31.3559 26.3094 31.3644 26.6011C31.3686 26.7609 31.3007 26.9134 31.1798 27.0177L27.5329 30.1471L23.8859 27.0834C23.6621 26.8949 23.6335 26.5608 23.8223 26.3369C23.9231 26.2172 24.0726 26.1484 24.2296 26.1489L25.3811 26.1526V19.0321C25.3811 18.4471 25.8563 17.9732 26.4419 17.9732H26.4445L28.5735 17.9769C29.1585 17.9785 29.6316 18.4518 29.6316 19.0358V19.0358Z" stroke="#797979" stroke-linejoin="round"/>
<defs>
<filter id="filter0_d_223_29" x="0" y="0" width="55" height="55" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="2.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_223_29"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_223_29" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,18 @@
<svg width="55" height="55" viewBox="0 0 55 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_223_29)">
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
</g>
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4327 31.208H20.3764C20.6649 31.208 20.9402 31.3245 21.1401 31.532L23.3285 33.7963C23.5285 34.0028 23.8037 34.1198 24.0923 34.1198H31.0456C31.3336 34.1198 31.6094 34.0033 31.8094 33.7963L33.9972 31.532C34.1972 31.325 34.473 31.208 34.7609 31.208H37.5879C38.1734 31.208 38.6487 31.6818 38.6487 32.2668V35.9727C38.6487 36.5577 38.1734 37.0315 37.5879 37.0315H17.4333C16.8472 37.0315 16.3725 36.5577 16.3725 35.9727V32.2668C16.3725 31.6818 16.8472 31.208 17.4333 31.208H17.4327ZM29.6316 19.0358V26.1214L30.8186 26.087C31.1114 26.0785 31.3559 26.3094 31.3644 26.6011C31.3686 26.7609 31.3007 26.9134 31.1798 27.0177L27.5329 30.1471L23.8859 27.0834C23.6621 26.8949 23.6335 26.5608 23.8223 26.3369C23.9231 26.2172 24.0726 26.1484 24.2296 26.1489L25.3811 26.1526V19.0321C25.3811 18.4471 25.8563 17.9732 26.4419 17.9732H26.4445L28.5735 17.9769C29.1585 17.9785 29.6316 18.4518 29.6316 19.0358V19.0358Z" stroke="#797979" stroke-linejoin="round"/>
<defs>
<filter id="filter0_d_223_29" x="0" y="0" width="55" height="55" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="2.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_223_29"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_223_29" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,33 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="173" height="178" viewBox="0 0 173 178">
<defs>
<ellipse id="37ng76i1qb" cx="42.422" cy="42.5" rx="42.422" ry="42.5"/>
<filter id="7z30ci9zua" width="117.7%" height="117.6%" x="-8.8%" y="-8.8%" filterUnits="objectBoundingBox">
<feOffset in="SourceAlpha" result="shadowOffsetOuter1"/>
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="2.5"/>
<feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd">
<g>
<g>
<path fill="#42B9FE" fill-opacity=".3" d="M78.031 168c48.523 0 113.902-43.009 86.32-95.233C136.77 20.542 136.033 7 93.437 7 50.841 7 .905 28.222.905 90.687.905 153.152 29.508 168 78.03 168z" transform="translate(-661 -387) translate(661 387)"/>
<g>
<g transform="translate(-661 -387) translate(661 387) translate(1.905) rotate(-15 97.339 11.047)">
<rect width="89.361" height="112.826" x=".165" y="5.209" fill="#0782C9" fill-opacity=".5" rx="2"/>
<rect width="89.361" height="112.826" x="4.716" y=".233" fill="#FFF" stroke="#0782C9" stroke-linejoin="round" stroke-width="2" rx="2"/>
<rect width="52.804" height="4.964" x="24.04" y="32.43" fill="#0782C9" rx="2.482"/>
<rect width="52.804" height="4.964" x="26.63" y="53.977" fill="#0782C9" rx="2.482"/>
<rect width="36.557" height="4.964" x="24.523" y="76.287" fill="#0782C9" rx="2.482"/>
</g>
<g>
<g transform="translate(-661 -387) translate(661 387) translate(1.905) translate(80.654 88.496)">
<use fill="#000" filter="url(#7z30ci9zua)" xlink:href="#37ng76i1qb"/>
<use fill="#42B9FE" xlink:href="#37ng76i1qb"/>
</g>
<path stroke="#FFF" stroke-linejoin="round" stroke-width="2" d="M23.441 49.504h5.55c.544 0 1.063.22 1.44.612l4.126 4.277c.377.39.896.611 1.44.611h13.11c.543 0 1.063-.22 1.44-.611l4.125-4.277c.377-.391.897-.612 1.44-.612h5.33c1.104 0 2 .895 2 2v7c0 1.105-.896 2-2 2h-38c-1.105 0-2-.895-2-2v-7c0-1.105.895-2 2-2zM46.441 26.512v13.384h0l2.238-.065c.552-.016 1.013.42 1.029.971.008.302-.12.59-.348.787L42.484 47.5h0l-6.876-5.787c-.422-.356-.476-.987-.12-1.41.19-.226.472-.356.768-.355l2.171.007h0v-13.45c0-1.105.896-2 2-2h.005l4.014.007c1.103.003 1.995.897 1.995 2z" transform="translate(-661 -387) translate(661 387) translate(1.905) translate(80.654 88.496)"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

+4 -1
View File
@@ -1,8 +1,11 @@
export const environment = { export const environment = {
production: true,
apiURL: 'https://gabinetedigital.dyndns.info/GabineteDigital.Services/V5/api/', apiURL: 'https://gabinetedigital.dyndns.info/GabineteDigital.Services/V5/api/',
apiChatUrl: 'https://gabinetedigitalchat.dyndns.info/api/v1/', apiChatUrl: 'https://gabinetedigitalchat.dyndns.info/api/v1/',
apiWsChatUrl: 'wss://gabinetedigitalchat.dyndns.info/websocket', apiWsChatUrl: 'wss://gabinetedigitalchat.dyndns.info/websocket',
//apiChatUrl: 'https://www.tabularium.pt/api/v1/',
production: true,
domain: 'gabinetedigital.local', domain: 'gabinetedigital.local',
defaultuser: '',//paulo.pinto paulo.pinto@gabinetedigital.local defaultuser: '',//paulo.pinto paulo.pinto@gabinetedigital.local
defaultuserpwd: '', //tabteste@006, defaultuserpwd: '', //tabteste@006,
+10 -2
View File
@@ -1148,9 +1148,16 @@ ngx-mat-datetime-content{
} }
} }
.audio-contentainer{ .audio-contentainer{
width: 200px !important; min-width: 200px !important;
display: flex; display: flex;
overflow: auto !important; overflow: auto !important;
.icon-download{
font-size:35px !important;
}
.item-prior-download{
--background:#000000e7;
}
} }
.title{ .title{
@@ -1190,7 +1197,8 @@ ngx-mat-datetime-content{
} }
.add-attachment-bg-color{ .add-attachment-bg-color{
background-color: #42b9fe13; background-color: #42b9fe13 !important;
--background: #42b9fe0a !important;
} }
.message-attachments{ .message-attachments{