mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
Downaload file on chat done
This commit is contained in:
@@ -1,15 +1,18 @@
|
|||||||
<ion-header class="ion-no-border">
|
<ion-header class="ion-no-border">
|
||||||
<ion-toolbar class="header-toolbar">
|
<ion-toolbar class="header-toolbar">
|
||||||
<div class="main-header">
|
<div class="main-header">
|
||||||
<div class="header-top">
|
<div class="header-top">
|
||||||
<div class="middle" *ngFor="let users of dmUsers">
|
<div class="middle" *ngFor="let users of dmUsers">
|
||||||
<ion-label class="title">{{users.name}}</ion-label>
|
<ion-label class="title">{{users.name}}</ion-label>
|
||||||
<span><ion-icon class="{{users.status}}" name="ellipse"></ion-icon></span>
|
<span>
|
||||||
|
<ion-icon class="{{users.status}}" name="ellipse"></ion-icon>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<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>
|
||||||
@@ -31,7 +34,7 @@
|
|||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
|
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
|
||||||
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
|
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
|
||||||
<ion-refresher-content>
|
<ion-refresher-content>
|
||||||
</ion-refresher-content>
|
</ion-refresher-content>
|
||||||
@@ -40,7 +43,8 @@
|
|||||||
<div class="messages-list-item-wrapper container-width-100" *ngFor="let msg of messages; let last = last">
|
<div class="messages-list-item-wrapper container-width-100" *ngFor="let msg of messages; let last = last">
|
||||||
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45'>
|
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45'>
|
||||||
<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>
|
||||||
@@ -54,9 +58,11 @@
|
|||||||
{{last ? scrollToBottom() : ''}}
|
{{last ? scrollToBottom() : ''}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45' *ngIf="msg.alias == 'documento'">
|
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45'
|
||||||
|
*ngIf="msg.alias == 'documento'">
|
||||||
<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>
|
||||||
@@ -73,28 +79,32 @@
|
|||||||
<div (click)="downloadFileMsg(msg)" dfsdvsvs>
|
<div (click)="downloadFileMsg(msg)" dfsdvsvs>
|
||||||
<!-- <img *ngIf="file.image_url" src="{{file.image_url}}" alt="image" (click)="imageSize(file.image_url)"> -->
|
<!-- <img *ngIf="file.image_url" src="{{file.image_url}}" alt="image" (click)="imageSize(file.image_url)"> -->
|
||||||
<img src={{msg.image_url}} alt="image">
|
<img src={{msg.image_url}} alt="image">
|
||||||
<!-- <div (click)="openPreview(msg)">
|
<!-- <div (click)="openPreview(msg)">
|
||||||
<img *ngIf="file.image_url" src="{{file.image_url}}" alt="image"> -->
|
<img *ngIf="file.image_url" src="{{file.image_url}}" alt="image"> -->
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="msg.file">
|
<div *ngIf="msg.file">
|
||||||
<div class="file">
|
<div class="file">
|
||||||
<div (click)="viewDocument(msg, file.title_link)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
|
<div (click)="viewDocument(msg, file.title_link)" class="file-details add-ellipsis cursor-pointer"
|
||||||
<span *ngIf="msg.file.type">
|
*ngIf="msg.file">
|
||||||
<fa-icon *ngIf="msg.file.type == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
|
<span *ngIf="msg.file.type">
|
||||||
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-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/vnd.openxmlformats-officedocument.spreadsheetml.sheet'" icon="file-word" class="excel-icon"></fa-icon>
|
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-icon"></fa-icon>
|
||||||
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-icon>
|
<fa-icon
|
||||||
<ion-icon *ngIf="msg.file.type == 'application/meeting'" src="assets/icon/webtrix.svg"></ion-icon>
|
*ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"
|
||||||
</span>
|
icon="file-word" class="excel-icon"></fa-icon>
|
||||||
<ion-label class="file-title">{{file.title}}</ion-label>
|
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-icon>
|
||||||
</div>
|
<ion-icon *ngIf="msg.file.type == 'application/meeting'" src="assets/icon/webtrix.svg"></ion-icon>
|
||||||
|
</span>
|
||||||
|
<ion-label class="file-title">{{file.title}}</ion-label>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-details-optional">
|
</div>
|
||||||
<ion-label *ngIf="msg.file">
|
<div class="file-details-optional">
|
||||||
<span *ngIf="file.description">{{file.description}}</span>
|
<ion-label *ngIf="msg.file">
|
||||||
<span *ngIf="file.description && msg.file.type != 'application/webtrix'"> • </span>
|
<span *ngIf="file.description">{{file.description}}</span>
|
||||||
<span *ngIf="msg.file.type != 'application/webtrix'">{{msg.file.type.replace('application/','').toUpperCase()}}</span>
|
<span *ngIf="file.description && msg.file.type != 'application/webtrix'"> • </span>
|
||||||
</ion-label>
|
<span
|
||||||
|
*ngIf="msg.file.type != 'application/webtrix'">{{msg.file.type.replace('application/','').toUpperCase()}}</span>
|
||||||
|
</ion-label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,12 +113,51 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="msg.file" >
|
|
||||||
|
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45' *ngIf="msg.msg ==''">
|
||||||
|
<div *ngIf="msg.file.type == 'application/img'">
|
||||||
|
<div class="message-item-options d-flex justify-content-end">
|
||||||
|
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer">
|
||||||
|
</fa-icon>
|
||||||
|
<mat-menu #beforeMenu="matMenu" xPosition="before">
|
||||||
|
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
|
||||||
|
</mat-menu>
|
||||||
|
</div>
|
||||||
|
<div class="title">
|
||||||
|
<ion-label>{{msg.u.name}}</ion-label>
|
||||||
|
<span class="time">{{showDateDuration(msg._updatedAt)}}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ion-label>{{msg.msg}}</ion-label>
|
||||||
|
<div *ngIf="msg.file" class="message-attachments">
|
||||||
|
<div>
|
||||||
|
<div (click)="openPreview(msg)">
|
||||||
|
<!-- <img *ngIf="file.image_url" src="{{file.image_url}}" alt="image" (click)="imageSize(file.image_url)"> -->
|
||||||
|
TTTT
|
||||||
|
<img *ngIf="msg.file.image_url" src="{{msg.file.image_url}}" alt="image">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{last ? scrollToBottom() : ''}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngIf="msg.file">
|
||||||
<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 />
|
<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>
|
||||||
@@ -156,7 +205,8 @@
|
|||||||
|
|
||||||
<div class="width-100">
|
<div class="width-100">
|
||||||
<ion-item class="ion-no-padding type-message" lines="none">
|
<ion-item class="ion-no-padding type-message" lines="none">
|
||||||
<ion-textarea (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem" class="message-input" rows="1" [(ngModel)]="message"></ion-textarea>
|
<ion-textarea (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem"
|
||||||
|
class="message-input" rows="1" [(ngModel)]="message"></ion-textarea>
|
||||||
<button hidden class="btn-no-color" (click)="notImplemented()">
|
<button hidden class="btn-no-color" (click)="notImplemented()">
|
||||||
<ion-icon slot="end" src="assets/icon/icons-chat-mic.svg"></ion-icon>
|
<ion-icon slot="end" src="assets/icon/icons-chat-mic.svg"></ion-icon>
|
||||||
</button>
|
</button>
|
||||||
@@ -164,14 +214,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button *ngIf="message" class="btn-no-color" (click)="sendMessage()">
|
<button *ngIf="message" class="btn-no-color" (click)="sendMessage()">
|
||||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send"
|
||||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
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="!message" class="btn-no-color">
|
<button *ngIf="!message" class="btn-no-color">
|
||||||
<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 == 'default' " class="chat-icon-send"
|
||||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
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>
|
||||||
</ion-footer>
|
</ion-footer>
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
console.log("Chat route", this.route.url)
|
console.log("Chat route", this.route.url)
|
||||||
|
|
||||||
this.setStatus('online');
|
this.setStatus('online');
|
||||||
this.getMessageDB();
|
//this.getMessageDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressingMessage() {
|
onPressingMessage() {
|
||||||
@@ -272,55 +272,57 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getImageFromStorage (element) {
|
async transformData(res) {
|
||||||
let image;
|
|
||||||
if (typeof element.file != 'undefined') {
|
|
||||||
if (typeof element.file.guid != 'undefined') {
|
|
||||||
let imageguid = this.storage.get(element.file.guid);
|
|
||||||
if (imageguid) {
|
|
||||||
image = imageguid;
|
|
||||||
console.log('IMAGE STORAGE', image)
|
|
||||||
} else {
|
|
||||||
image = "";
|
|
||||||
console.log('IMAGE STORAGE', image)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
image = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('IMAGE STORAGE RETURN', image.__zone_symbol__value)
|
|
||||||
return image.__zone_symbol__value;
|
|
||||||
}
|
|
||||||
|
|
||||||
transformData(res) {
|
|
||||||
let mgsArray = [];
|
let mgsArray = [];
|
||||||
res.forEach(async element => {
|
res.map(async element => {
|
||||||
|
|
||||||
let chatmsg = {
|
if (element.file) {
|
||||||
_id: element._id,
|
if (element.file.guid) {
|
||||||
attachments: element.attachments,
|
await this.storage.get(element.file.guid).then((image) => {
|
||||||
channels: element.channels,
|
let chatmsg = {
|
||||||
file: element.file,
|
_id: element._id,
|
||||||
mentions: element.mentions,
|
attachments: element.attachments,
|
||||||
msg: element.msg,
|
channels: element.channels,
|
||||||
rid: element.rid,
|
file: {
|
||||||
ts: element.ts,
|
guid: element.file.guid,
|
||||||
u: element.u,
|
image_url: image,
|
||||||
_updatedAt: element._updatedAt,
|
type: element.file.type
|
||||||
image_url: this.getImageFromStorage(element),
|
},
|
||||||
|
mentions: element.mentions,
|
||||||
|
msg: element.msg,
|
||||||
|
rid: element.rid,
|
||||||
|
ts: element.ts,
|
||||||
|
u: element.u,
|
||||||
|
_updatedAt: element._updatedAt,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mgsArray.push(chatmsg)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let chatmsg = {
|
||||||
|
_id: element._id,
|
||||||
|
attachments: element.attachments,
|
||||||
|
channels: element.channels,
|
||||||
|
mentions: element.mentions,
|
||||||
|
msg: element.msg,
|
||||||
|
rid: element.rid,
|
||||||
|
ts: element.ts,
|
||||||
|
u: element.u,
|
||||||
|
_updatedAt: element._updatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
mgsArray.push(chatmsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
mgsArray.push(chatmsg)
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
console.log('Web TRANSFORM MSG', mgsArray)
|
await this.storage.remove('chatmsg').then(() => {
|
||||||
this.storage.remove('chatmsg').then(() => {
|
|
||||||
console.log('MSG REMOVE FROM STORAGE')
|
console.log('MSG REMOVE FROM STORAGE')
|
||||||
});
|
});
|
||||||
this.storage.set('chatmsg', mgsArray).then(() => {
|
await this.storage.set('chatmsg', mgsArray).then((value) => {
|
||||||
console.log('MSG SAVED ON STORAGE')
|
console.log('MSG SAVED ON STORAGE', value)
|
||||||
this.getMessageDB();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -328,10 +330,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
loadMessages() {
|
loadMessages() {
|
||||||
//this.showLoader = true;
|
//this.showLoader = true;
|
||||||
const roomId = this.roomId
|
const roomId = this.roomId
|
||||||
this.chatService.getRoomMessages(this.roomId).subscribe(res => {
|
this.chatService.getRoomMessages(this.roomId).subscribe(async res => {
|
||||||
console.log('ALL MSG FROM CHATROCK', res);
|
console.log('ALL MSG FROM CHATROCK', res);
|
||||||
this.transformData(res['messages']);
|
await this.transformData(res['messages']);
|
||||||
this.getMessageDB();
|
|
||||||
//this.getFileFromLakeFS();
|
//this.getFileFromLakeFS();
|
||||||
/* this.messages = res['messages'].reverse();
|
/* this.messages = res['messages'].reverse();
|
||||||
this.chatMessageStore.add(roomId, this.messages) */
|
this.chatMessageStore.add(roomId, this.messages) */
|
||||||
@@ -705,10 +706,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
// Show Error
|
// Show Error
|
||||||
//showMessage(response.statusText);
|
//showMessage(response.statusText);
|
||||||
console.log('ALL MSG FROM CHATROCK', res);
|
console.log('ALL MSG FROM CHATROCK', res);
|
||||||
/* this.transformData(res['messages']);
|
/* this.transformData(res['messages']);*/
|
||||||
this.getMessageDB(); */
|
await this.transformData(res['messages']);
|
||||||
this.transformData(res['messages']);
|
|
||||||
this.getMessageDB();
|
this.getMessageDB();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this.messages = res['messages'].reverse();
|
this.messages = res['messages'].reverse();
|
||||||
this.chatMessageStore.add(roomId, this.messages) */
|
this.chatMessageStore.add(roomId, this.messages) */
|
||||||
@@ -827,7 +828,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
async openPreview(msg) {
|
async openPreview(msg) {
|
||||||
if (msg.image_url = "") {
|
if (msg.file.image_url === null) {
|
||||||
|
this.downloadFileMsg(msg)
|
||||||
|
} else {
|
||||||
const modal = await this.modalController.create({
|
const modal = await this.modalController.create({
|
||||||
component: ViewMediaPage,
|
component: ViewMediaPage,
|
||||||
cssClass: 'modal modal-desktop',
|
cssClass: 'modal modal-desktop',
|
||||||
@@ -838,8 +841,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
modal.present();
|
modal.present();
|
||||||
} else {
|
|
||||||
this.downloadFileMsg(msg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user