@chat21/chat21-ionic 3.4.29 → 3.4.30-rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -2
- package/angular.json +1 -0
- package/package.json +1 -1
- package/src/app/app.component.html +3 -1
- package/src/app/app.component.ts +71 -12
- package/src/app/chatlib/conversation-detail/message/image/image.component.html +1 -0
- package/src/app/chatlib/conversation-detail/message/image/image.component.ts +19 -0
- package/src/app/components/canned-response/canned-response.component.html +26 -23
- package/src/app/components/canned-response/canned-response.component.scss +0 -2
- package/src/app/components/canned-response/canned-response.component.ts +3 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +24 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +30 -0
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +39 -9
- package/src/app/components/conversation-info/info-content/info-content.component.ts +2 -2
- package/src/app/components/conversation-info/info-group/info-group.component.ts +23 -21
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +5 -1
- package/src/app/components/navbar/navbar.component.html +3 -3
- package/src/app/components/navbar/navbar.component.ts +29 -38
- package/src/app/components/project-item/project-item.component.ts +11 -11
- package/src/app/components/sidebar/sidebar.component.html +65 -45
- package/src/app/components/sidebar/sidebar.component.ts +110 -117
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +2 -2
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +10 -7
- package/src/app/modals/create-ticket/create-ticket.page.ts +4 -2
- package/src/app/pages/conversation-detail/conversation-detail.page.html +7 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +95 -7
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +40 -2
- package/src/app/services/global-settings/global-settings.service.ts +11 -3
- package/src/app/services/nav-proxy.service.ts +0 -1
- package/src/app/services/project_users/project-users.service.spec.ts +16 -0
- package/src/app/services/project_users/project-users.service.ts +63 -0
- package/src/app/services/tiledesk/tiledesk.service.ts +0 -16
- package/src/app/services/triggerEvents/triggerEvents.ts +28 -0
- package/src/app/services/websocket/websocket-js.ts +59 -534
- package/src/app/services/websocket/websocket-js_old.ts +578 -0
- package/src/app/services/websocket/websocket.service.ts +9 -10
- package/src/app/services/websocket/websocket.worker.ts +242 -0
- package/src/app/shared/shared.module.ts +11 -2
- package/src/app/utils/globals.ts +2 -0
- package/src/app/utils/permissions.constants.ts +138 -0
- package/src/app/utils/project-utils.ts +2 -2
- package/src/app/utils/utils.ts +18 -1
- package/src/assets/i18n/ar.json +11 -1
- package/src/assets/i18n/az.json +11 -1
- package/src/assets/i18n/de.json +11 -1
- package/src/assets/i18n/en.json +11 -1
- package/src/assets/i18n/es.json +11 -1
- package/src/assets/i18n/fr.json +11 -1
- package/src/assets/i18n/it.json +13 -3
- package/src/assets/i18n/kk.json +11 -1
- package/src/assets/i18n/pt.json +11 -1
- package/src/assets/i18n/ru.json +11 -1
- package/src/assets/i18n/sr.json +11 -1
- package/src/assets/i18n/sv.json +11 -1
- package/src/assets/i18n/tr.json +11 -1
- package/src/assets/i18n/uk.json +11 -1
- package/src/assets/i18n/uz.json +12 -1
- package/src/assets/img/no_data_found.png +0 -0
- package/src/assets/js/agentDesktop-sdk.js +55 -0
- package/src/assets/js/chat21client.js +36 -0
- package/src/assets/js/mqtt-keepalive-worker.js +53 -0
- package/src/assets/test.html +5 -2
- package/src/chat-config-template.json +1 -0
- package/src/chat-config.json +1 -0
- package/src/chat21-core/models/projectUsers.ts +19 -0
- package/src/chat21-core/providers/abstract/upload.service.ts +5 -1
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +136 -9
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
- package/src/chat21-core/providers/native/native-upload-service.ts +143 -45
- package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
- package/src/chat21-core/utils/utils.ts +16 -2
package/src/assets/i18n/pt.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrador",
|
|
226
226
|
"agent": "Agente",
|
|
227
227
|
"Conversations": "Conversas",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Fluxos",
|
|
230
|
+
"Knowledgebases": "Bases de Conhecimento",
|
|
231
|
+
"Whatsappbroadcasts": "Transmissões do WhatsApp",
|
|
228
232
|
"Apps":"Aplicativos",
|
|
229
233
|
"Analytics":"Análise",
|
|
230
234
|
"Activities": "Atividades",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Mensagem também enviada por e-mail 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji não permitido",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "O URL contém um domínio não permitido"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "O URL contém um domínio não permitido",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Abrir Ticket",
|
|
316
|
+
"DESCRIPTION": "Confirma que deseja abrir um ticket para esta conversa?",
|
|
317
|
+
"CONFIRM": "Confirmar",
|
|
318
|
+
"CLOSE": "Fechar"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/ru.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Администратор",
|
|
226
226
|
"agent": "Агент",
|
|
227
227
|
"Conversations": "Разговоры",
|
|
228
|
+
"Monitor": "Монитор",
|
|
229
|
+
"Flows": "Потоки",
|
|
230
|
+
"Knowledgebases": "Базы знаний",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp-рассылки",
|
|
228
232
|
"Apps":"Приложения",
|
|
229
233
|
"Analytics":"Аналитика",
|
|
230
234
|
"Activities": "Виды деятельности",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Сообщение также отправлено по электронной почте 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Эмодзи не разрешены",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL содержит недопустимый домен"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL содержит недопустимый домен",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Открыть тикет",
|
|
316
|
+
"DESCRIPTION": "Вы подтверждаете, что хотите открыть тикет для этого разговора?",
|
|
317
|
+
"CONFIRM": "Подтвердить",
|
|
318
|
+
"CLOSE": "Закрыть"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/sr.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Aдминистратор",
|
|
226
226
|
"agent": "Агент",
|
|
227
227
|
"Conversations": "Разговори",
|
|
228
|
+
"Monitor": "Монитор",
|
|
229
|
+
"Flows": "Токови",
|
|
230
|
+
"Knowledgebases": "Baze znanja",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp emitovanja",
|
|
228
232
|
"Apps":"Аппс",
|
|
229
233
|
"Analytics":"Аналитика",
|
|
230
234
|
"Activities": "Активности",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Порука је такође послата е-поштом 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emodžiji nisu dozvoljeni",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL sadrži nedozvoljenu domenu"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL sadrži nedozvoljenu domenu",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Otvori tiket",
|
|
316
|
+
"DESCRIPTION": "Da li potvrđujete da želite da otvorite tiket za ovaj razgovor?",
|
|
317
|
+
"CONFIRM": "Potvrdi",
|
|
318
|
+
"CLOSE": "Zatvori"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/sv.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administratör",
|
|
226
226
|
"agent": "Ombud",
|
|
227
227
|
"Conversations": "Samtal",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Flöden",
|
|
230
|
+
"Knowledgebases": "Kunskapsbaser",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp-sändningar",
|
|
228
232
|
"Apps": "Appar",
|
|
229
233
|
"Analytics": "Analytics",
|
|
230
234
|
"Activities": "Aktiviteter",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Meddelande skickas även via mail 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji är inte tillåtna",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL:en innehåller en otillåten domän"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL:en innehåller en otillåten domän",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Öppna Ärende",
|
|
316
|
+
"DESCRIPTION": "Bekräftar du att du vill öppna ett ärende för den här konversationen?",
|
|
317
|
+
"CONFIRM": "Bekräfta",
|
|
318
|
+
"CLOSE": "Stäng"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/tr.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Yönetici",
|
|
226
226
|
"agent": "Ajan",
|
|
227
227
|
"Conversations": "Konuşmalar",
|
|
228
|
+
"Monitor": "Monitör",
|
|
229
|
+
"Flows": "Akışlar",
|
|
230
|
+
"Knowledgebases": "Bilgi Tabanları",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp Yayınları",
|
|
228
232
|
"Apps":"Uygulamalar",
|
|
229
233
|
"Analytics":"Analitik",
|
|
230
234
|
"Activities": "Faaliyetler",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Mesaj ayrıca e-posta ile gönderilir 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji'ye izin verilmiyor",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL izin verilmeyen bir alan adı içeriyor"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL izin verilmeyen bir alan adı içeriyor",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Bilet Aç",
|
|
316
|
+
"DESCRIPTION": "Bu görüşme için bir bilet açmak istediğinizi onaylıyor musunuz?",
|
|
317
|
+
"CONFIRM": "Onayla",
|
|
318
|
+
"CLOSE": "Kapat"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/uk.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Адміністратор",
|
|
226
226
|
"agent": "Агент",
|
|
227
227
|
"Conversations": "Бесіди",
|
|
228
|
+
"Monitor": "Монітор",
|
|
229
|
+
"Flows": "Потоки",
|
|
230
|
+
"Knowledgebases": "Бази знань",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp-розсилки",
|
|
228
232
|
"Apps": "Програми",
|
|
229
233
|
"Analytics": "Аналітика",
|
|
230
234
|
"Activities": "Діяльність",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Повідомлення також надіслано електронною поштою 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Емодзі не дозволені",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL містить недозволений домен"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL містить недозволений домен",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Відкрити тікет",
|
|
316
|
+
"DESCRIPTION": "Підтверджуєте, що хочете відкрити тікет для цієї розмови?",
|
|
317
|
+
"CONFIRM": "Підтвердити",
|
|
318
|
+
"CLOSE": "Закрити"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/uz.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrator",
|
|
226
226
|
"agent": "Agent",
|
|
227
227
|
"Conversations": "Suhbatlar",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Oqimlar",
|
|
230
|
+
"Knowledgebases": "Bilim bazalari",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp efirlarini yuborish",
|
|
228
232
|
"Apps": "Ilovalar",
|
|
229
233
|
"Analytics": "Analitika",
|
|
230
234
|
"Activities": "Faoliyatlar",
|
|
@@ -306,5 +310,12 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Xabar elektron pochta orqali ham yuborildi 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji'ga ruxsat berilmagan",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL ruxsat etilmagan domenni o'z ichiga oladi"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL ruxsat etilmagan domenni o'z ichiga oladi",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Chiptani ochish",
|
|
316
|
+
"DESCRIPTION": "Ushbu suhbat uchun chipta ochmoqchi ekanligingizni tasdiqlaysizmi?",
|
|
317
|
+
"CONFIRM": "Tasdiqlash",
|
|
318
|
+
"CLOSE": "Yopish"
|
|
319
|
+
}
|
|
320
|
+
|
|
310
321
|
}
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function loadAgentDesktopScript() {
|
|
2
|
+
if (document.getElementById('agentdesktop-sdk')) {
|
|
3
|
+
return;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const script = document.createElement('script');
|
|
7
|
+
script.id = 'agentdesktop-sdk';
|
|
8
|
+
script.type = 'text/javascript';
|
|
9
|
+
script.src = 'https://devcti.aruba.it/AD/widget/agentdesktop_widget.js';
|
|
10
|
+
script.async = true;
|
|
11
|
+
|
|
12
|
+
script.onload = () => {
|
|
13
|
+
console.log('AgentDesktop SDK caricato');
|
|
14
|
+
window.agentDesktopLoaded = true;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
script.onerror = (error) => {
|
|
18
|
+
console.error('Errore nel caricamento AgentDesktop SDK', error);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if (document.body) {
|
|
27
|
+
document.body.appendChild(script);
|
|
28
|
+
} else {
|
|
29
|
+
window.addEventListener('DOMContentLoaded', function() {
|
|
30
|
+
document.body.appendChild(script);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function openTicketOnHDA(requestId){
|
|
37
|
+
console.log('openTicketOnHDA called with requestId:', requestId);
|
|
38
|
+
const message = { companyID: "1", sourceID: "CHAT", tiledeskID: requestId, target: "HDA", origin: "Tiledesk" }
|
|
39
|
+
if(window && window.parent){
|
|
40
|
+
window.parent.postMessage(message, 'https://devhda2bo.aruba.it/HDAPortal/');
|
|
41
|
+
window.postMessage(message, 'https://devhda2bo.aruba.it/HDAPortal/');
|
|
42
|
+
console.log('Message posted to parent window and current window');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if(window['AGENTDESKTOP']){
|
|
46
|
+
console.log('AGENTDESKTOP exist. Sending message . . .');
|
|
47
|
+
window['AGENTDESKTOP']['WIDGET'].sendDataToWidget('PAT', JSON.stringify(message)); // invia il messaggio ad HDA
|
|
48
|
+
AGENTDESKTOP.TAB.GoTo('PAT'); // dà il focus ad HDA
|
|
49
|
+
console.log('Message sent to AGENTDESKTOP widget');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
loadAgentDesktopScript();
|
|
@@ -1010,6 +1010,7 @@ class Chat21Client {
|
|
|
1010
1010
|
this.start( () => {
|
|
1011
1011
|
// callback();
|
|
1012
1012
|
});
|
|
1013
|
+
this.initKeepAliveWorker()
|
|
1013
1014
|
}
|
|
1014
1015
|
this.client.publish(
|
|
1015
1016
|
this.presence_topic,
|
|
@@ -1027,6 +1028,36 @@ class Chat21Client {
|
|
|
1027
1028
|
console.error("Chat client error event", error);
|
|
1028
1029
|
}
|
|
1029
1030
|
);
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
initKeepAliveWorker(){
|
|
1037
|
+
this.worker= new Worker('assets/js/mqtt-keepalive-worker.js');
|
|
1038
|
+
if (this.log) {
|
|
1039
|
+
console.log("Chat21Client - initKeepAliveWorker() - worker created", this.worker);
|
|
1040
|
+
}
|
|
1041
|
+
// this.worker.postMessage({
|
|
1042
|
+
// action: 'start',
|
|
1043
|
+
// user_id: this.user_id,
|
|
1044
|
+
// client_id: this.client_id,
|
|
1045
|
+
// jwt: this.jwt,
|
|
1046
|
+
// endpoint: this.endpoint
|
|
1047
|
+
// });
|
|
1048
|
+
this.worker.onmessage = (event) => {
|
|
1049
|
+
if (event.data.action === 'ping') {
|
|
1050
|
+
if (this.client && this.client.connected) {
|
|
1051
|
+
// questo non causa refresh di niente
|
|
1052
|
+
this.client.publish(
|
|
1053
|
+
`apps/tilechat/users/${this.user_id}/keepalive`,
|
|
1054
|
+
JSON.stringify({ ts: Date.now() })
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
this.worker.postMessage({ action: 'ping' });
|
|
1030
1061
|
}
|
|
1031
1062
|
|
|
1032
1063
|
onDisconnect(callback){
|
|
@@ -1041,6 +1072,11 @@ class Chat21Client {
|
|
|
1041
1072
|
this.connected = false
|
|
1042
1073
|
if (this.log) {console.log("Chat client close event");}
|
|
1043
1074
|
callback('close')
|
|
1075
|
+
if (this.worker) {
|
|
1076
|
+
this.worker.postMessage({ action: 'stop' });
|
|
1077
|
+
this.worker.terminate();
|
|
1078
|
+
this.worker = null;
|
|
1079
|
+
}
|
|
1044
1080
|
}
|
|
1045
1081
|
);
|
|
1046
1082
|
this.client.on('offline',
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
importScripts('https://unpkg.com/mqtt/dist/mqtt.min.js');
|
|
2
|
+
|
|
3
|
+
let client = null;
|
|
4
|
+
let user_id = null;
|
|
5
|
+
let pingIntervalId = null;
|
|
6
|
+
self.onmessage = function(event) {
|
|
7
|
+
const data = event.data;
|
|
8
|
+
|
|
9
|
+
// console.log('MQTT KEEPALIVE WORKER - received message ', data);
|
|
10
|
+
if (data.action === 'start') {
|
|
11
|
+
user_id = data.user_id;
|
|
12
|
+
const endpoint = data.endpoint;
|
|
13
|
+
const jwt = data.jwt;
|
|
14
|
+
|
|
15
|
+
const options = {
|
|
16
|
+
keepalive: 3, // basso keepalive
|
|
17
|
+
reconnectPeriod: 1000,
|
|
18
|
+
clientId: data.client_id,
|
|
19
|
+
username: 'JWT',
|
|
20
|
+
password: jwt,
|
|
21
|
+
rejectUnauthorized: false
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
client = mqtt.connect(endpoint, options);
|
|
25
|
+
|
|
26
|
+
client.on('connect', () => {
|
|
27
|
+
// start ping
|
|
28
|
+
pingIntervalId = setInterval(() => {
|
|
29
|
+
if (client && client.connected) {
|
|
30
|
+
// console.log('MQTT KEEPALIVE WORKER - sending keepalive ping for user ', user_id);
|
|
31
|
+
client.publish(`apps/tilechat/users/${user_id}/keepalive`,
|
|
32
|
+
JSON.stringify({ ts: new Date().getTime() }));
|
|
33
|
+
}
|
|
34
|
+
}, 3000);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
client.on('close', () => {
|
|
38
|
+
clearInterval(pingIntervalId);
|
|
39
|
+
pingIntervalId = null;
|
|
40
|
+
});
|
|
41
|
+
}else if (data.action === 'ping') {
|
|
42
|
+
if (self.timer) return;
|
|
43
|
+
|
|
44
|
+
self.timer = setInterval(() => {
|
|
45
|
+
postMessage({ action: 'ping' });
|
|
46
|
+
}, 3000);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (data.action === 'stop') {
|
|
50
|
+
if (pingIntervalId) clearInterval(pingIntervalId);
|
|
51
|
+
if (client) client.end();
|
|
52
|
+
}
|
|
53
|
+
};
|
package/src/assets/test.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width">
|
|
7
|
-
<title>
|
|
7
|
+
<title>Iframe test</title>
|
|
8
8
|
</head>
|
|
9
9
|
|
|
10
10
|
<body style="height: 100%;">
|
|
@@ -20,7 +20,10 @@
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<iframe id="myIFrame" frameBorder="0" width="100%" style="display: flex; height: 95vh" onload="onLoad()"
|
|
23
|
-
|
|
23
|
+
src="http://localhost:8080/#/conversation-detail?tiledesk_supportMode=true&jwt=JWT eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NWM1ZjM1OTlmYWYyZDA0Y2Q3ZGE1MjgiLCJlbWFpbCI6Imdpb3Zhbm5pQHRpbGVkZXNrLmNvbSIsImZpcnN0bmFtZSI6Ikdpb3Zhbm5pIiwibGFzdG5hbWUiOiJUcm9pc2kgQWRtIiwiZW1haWx2ZXJpZmllZCI6dHJ1ZSwiaWF0IjoxNzY0NjAyMTQxLCJhdWQiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsImlzcyI6Imh0dHBzOi8vdGlsZWRlc2suY29tIiwic3ViIjoidXNlciIsImp0aSI6IjIwNzZjYmMxLTI0NzgtNGU4MC1iZjFmLTBiZTA3MTQ3MjQ3MSJ9.R60xZC5M2n-hc-mRIMpA9KaUFxnBQHA_FrLyL9cCiqxeCitfCfbfA3_EKXWbWg3rDztmOR7SVjEO8Gyw_hdhKyjpx-OpaDAILw0dSsuBHB0R4h0F4fN2J_JJ60UIItXxoAq1AI9ML2cRGoRNAtfl6PMjpHXdbpdBAGcBYoGqGv3xWPlM7wOdIhGasnWT932DiscF3I_ltcFkS3naebQQfsgztlbU-UF7EcFjDc-mMzMxqnE1MYKzyqUAR9J9zFmqiUlCsl_J0TNhAjqUw-0GHXpzLQJN9dutVyH4y_MZxt_p6qAIzNo9LpMi-a5bfvQvpJjSuc9POvmlmWFAmwoQGw"
|
|
24
|
+
allow="autoplay; fullscreen; geolocation; microphone; camera; display-capture; encrypted-media; clipboard-read; clipboard-write;"
|
|
25
|
+
loading="eager" importance="high">
|
|
26
|
+
</iframe>
|
|
24
27
|
|
|
25
28
|
<script>
|
|
26
29
|
// window.addEventListener('message', event => {
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"wsUrlRel": "${WS_URL_RELATIVE}",
|
|
38
38
|
"storage_prefix": "${CHAT_STORAGE_PREFIX}",
|
|
39
39
|
"emailSection": "${EMAIL_SECTION}",
|
|
40
|
+
"ticketSection": "${TICKET_SECTION}",
|
|
40
41
|
"whatsappTemplatesSection":"${WHATSAPP_TEMPLATES_SECTION}",
|
|
41
42
|
"googleMapsApiKey":"${GOOGLE_MAPS_APIKEY}"
|
|
42
43
|
}
|
package/src/chat-config.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ProjectUser {
|
|
2
|
+
_id?: string;
|
|
3
|
+
updatedAt?: any;
|
|
4
|
+
createdAt?: any;
|
|
5
|
+
id_project?: string;
|
|
6
|
+
user_available?: boolean;
|
|
7
|
+
role?: string;
|
|
8
|
+
createdBy?: string;
|
|
9
|
+
is_group_member?: boolean;
|
|
10
|
+
// id_user?: string;
|
|
11
|
+
isAuthenticated?: boolean;
|
|
12
|
+
isBusy?: boolean;
|
|
13
|
+
status?: string;
|
|
14
|
+
id_user?: any;
|
|
15
|
+
rolePermissions?: string[];
|
|
16
|
+
profileStatus?: string;
|
|
17
|
+
presence?: { [key: string]: string}
|
|
18
|
+
__v?: any;
|
|
19
|
+
}
|
|
@@ -34,9 +34,13 @@ export abstract class UploadService {
|
|
|
34
34
|
// abstract tenant = environment.tenant;
|
|
35
35
|
|
|
36
36
|
// functions
|
|
37
|
-
abstract initialize(): void;
|
|
37
|
+
abstract initialize(projectId?: string): void;
|
|
38
38
|
abstract upload(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}>;
|
|
39
|
+
abstract uploadFile(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}>;
|
|
40
|
+
abstract uploadAsset(userId: string, upload: UploadModel, expiration?: number): Promise<{downloadURL: string, src: string}>;
|
|
39
41
|
abstract uploadProfile(userId: string, upload: UploadModel): Promise<any>;
|
|
40
42
|
abstract delete(userId: string, path: string): Promise<any>;
|
|
43
|
+
abstract deleteFile(userId: string, path: string): Promise<any>;
|
|
44
|
+
abstract deleteAsset(userId: string, path: string): Promise<any>
|
|
41
45
|
abstract deleteProfile(userId: string, path: string): Promise<any>
|
|
42
46
|
}
|
|
@@ -387,7 +387,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
387
387
|
} else {
|
|
388
388
|
|
|
389
389
|
if (message.attributes.messagelabel.parameters.firstname) {
|
|
390
|
-
// other user has been added to the group (and he has a
|
|
390
|
+
// other user has been added to the group (and he has a fullname)
|
|
391
391
|
subject = message.attributes.messagelabel.parameters.firstname;
|
|
392
392
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
393
393
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
@@ -42,7 +42,7 @@ export class FirebaseUploadService extends UploadService {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
public initialize() {
|
|
45
|
+
public async initialize(projectId?: string) {
|
|
46
46
|
this.logger.log('[FIREBASEUploadSERVICE] initialize');
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -104,6 +104,107 @@ export class FirebaseUploadService extends UploadService {
|
|
|
104
104
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
public uploadFile(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: any}> {
|
|
108
|
+
const that = this;
|
|
109
|
+
const uid = this.createGuid();
|
|
110
|
+
const urlImagesNodeFirebase = '/public/images/' + userId + '/' + uid + '/' + upload.file.name;
|
|
111
|
+
this.logger.debug('[FIREBASEUploadSERVICE] pushUpload ', urlImagesNodeFirebase, upload.file);
|
|
112
|
+
|
|
113
|
+
// Create a root reference
|
|
114
|
+
const storageRef = firebase.storage().ref();
|
|
115
|
+
this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
|
|
116
|
+
|
|
117
|
+
// Create a reference to 'mountains.jpg'
|
|
118
|
+
const mountainsRef = storageRef.child(urlImagesNodeFirebase);
|
|
119
|
+
this.logger.debug('[FIREBASEUploadSERVICE] mountainsRef ', mountainsRef);
|
|
120
|
+
|
|
121
|
+
// const metadata = {};
|
|
122
|
+
const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
|
|
123
|
+
|
|
124
|
+
let uploadTask = mountainsRef.put(upload.file, metadata);
|
|
125
|
+
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
uploadTask.on('state_changed', function progress(snapshot) {
|
|
128
|
+
// Observe state change events such as progress, pause, and resume
|
|
129
|
+
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
|
|
130
|
+
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
|
|
131
|
+
that.logger.debug('[FIREBASEUploadSERVICE] Upload is ' + progress + '% done');
|
|
132
|
+
|
|
133
|
+
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
|
134
|
+
// BehaviorSubject publish the upload progress state - the subscriber is in ion-conversastion-detail.component.ts > listenToUploadFileProgress()
|
|
135
|
+
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
that.BSStateUpload.next({ upload: progress, type: upload.file.type });
|
|
138
|
+
|
|
139
|
+
switch (snapshot.state) {
|
|
140
|
+
case firebase.storage.TaskState.PAUSED: // or 'paused'
|
|
141
|
+
that.logger.debug('[FIREBASEUploadSERVICE] Upload is paused');
|
|
142
|
+
|
|
143
|
+
break;
|
|
144
|
+
case firebase.storage.TaskState.RUNNING: // or 'running'
|
|
145
|
+
that.logger.debug('[FIREBASEUploadSERVICE] Upload is running');
|
|
146
|
+
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}, function error(error) {
|
|
150
|
+
// Handle unsuccessful uploads
|
|
151
|
+
reject(error)
|
|
152
|
+
}, async function complete() {
|
|
153
|
+
// Handle successful uploads on complete
|
|
154
|
+
that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
|
|
155
|
+
|
|
156
|
+
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
|
|
157
|
+
resolve({downloadURL: downloadURL, src: downloadURL})
|
|
158
|
+
// that.BSStateUpload.next({upload: upload});
|
|
159
|
+
|
|
160
|
+
});
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public uploadAsset(userId: string, upload: UploadModel, expiration: number = 60): Promise<{downloadURL: string, src: any}> {
|
|
165
|
+
// expiration is ignored on Firebase, but kept for API compatibility with NativeUploadService
|
|
166
|
+
const that = this;
|
|
167
|
+
const uid = this.createGuid();
|
|
168
|
+
const urlAssetsNodeFirebase = '/public/assets/' + userId + '/' + uid + '/' + upload.file.name;
|
|
169
|
+
this.logger.debug('[FIREBASEUploadSERVICE] uploadAsset ', urlAssetsNodeFirebase, upload.file, 'expiration:', expiration);
|
|
170
|
+
|
|
171
|
+
// Create a root reference
|
|
172
|
+
const storageRef = firebase.storage().ref();
|
|
173
|
+
this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
|
|
174
|
+
|
|
175
|
+
const assetRef = storageRef.child(urlAssetsNodeFirebase);
|
|
176
|
+
this.logger.debug('[FIREBASEUploadSERVICE] assetRef ', assetRef);
|
|
177
|
+
|
|
178
|
+
const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
|
|
179
|
+
|
|
180
|
+
let uploadTask = assetRef.put(upload.file, metadata);
|
|
181
|
+
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
uploadTask.on('state_changed', function progress(snapshot) {
|
|
184
|
+
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
|
|
185
|
+
that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is ' + progress + '% done');
|
|
186
|
+
|
|
187
|
+
that.BSStateUpload.next({ upload: progress, type: upload.file.type });
|
|
188
|
+
|
|
189
|
+
switch (snapshot.state) {
|
|
190
|
+
case firebase.storage.TaskState.PAUSED:
|
|
191
|
+
that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is paused');
|
|
192
|
+
break;
|
|
193
|
+
case firebase.storage.TaskState.RUNNING:
|
|
194
|
+
that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is running');
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}, function error(error) {
|
|
198
|
+
reject(error)
|
|
199
|
+
}, async function complete() {
|
|
200
|
+
that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is complete', upload);
|
|
201
|
+
|
|
202
|
+
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
|
|
203
|
+
resolve({downloadURL: downloadURL, src: downloadURL})
|
|
204
|
+
});
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
107
208
|
public uploadProfile(userId: string, upload: UploadModel): Promise<any> {
|
|
108
209
|
const that = this;
|
|
109
210
|
const urlImagesNodeFirebase = '/profiles/' + userId + '/photo.jpg'
|
|
@@ -192,6 +293,40 @@ export class FirebaseUploadService extends UploadService {
|
|
|
192
293
|
})
|
|
193
294
|
}
|
|
194
295
|
|
|
296
|
+
public async deleteFile(userId: string, path: string): Promise<any>{
|
|
297
|
+
const that = this;
|
|
298
|
+
const file_name_photo = 'photo.jpg';
|
|
299
|
+
const file_name_thumb_photo = 'thumb_photo.jpg';
|
|
300
|
+
|
|
301
|
+
that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
|
|
302
|
+
|
|
303
|
+
let uid = path.split(userId)[1].split('%2F')[1]; // get the UID of the image
|
|
304
|
+
let imageName = path.split(uid + '%2F')[1].split('?')[0];
|
|
305
|
+
|
|
306
|
+
// Create a root reference
|
|
307
|
+
const storageRef = firebase.storage().ref();
|
|
308
|
+
const ref = storageRef.child('public/images/' + userId + '/'+ uid + '/')
|
|
309
|
+
let arrayPromise = []
|
|
310
|
+
await ref.listAll().then((dir => {
|
|
311
|
+
dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
|
|
312
|
+
})).catch(error => {
|
|
313
|
+
that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
//AWAIT to return ALL the promise delete()
|
|
317
|
+
return new Promise((resolve, reject)=> {
|
|
318
|
+
Promise.all(arrayPromise).then(()=>{
|
|
319
|
+
resolve(true)
|
|
320
|
+
}).catch((error)=>{
|
|
321
|
+
reject(error)
|
|
322
|
+
})
|
|
323
|
+
})
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
public async deleteAsset(userId: string, path: string): Promise<any>{
|
|
327
|
+
return this.deleteProfile(userId, path);
|
|
328
|
+
}
|
|
329
|
+
|
|
195
330
|
public async deleteProfile(userId: string, path: string): Promise<any>{
|
|
196
331
|
const that = this;
|
|
197
332
|
const file_name_photo = 'photo.jpg';
|
|
@@ -219,13 +354,5 @@ export class FirebaseUploadService extends UploadService {
|
|
|
219
354
|
})
|
|
220
355
|
}
|
|
221
356
|
|
|
222
|
-
// // ------------------------------------
|
|
223
|
-
// // Delete the file photo
|
|
224
|
-
// // ------------------------------------
|
|
225
|
-
private deleteFile(pathToFile, fileName){
|
|
226
|
-
const ref = firebase.storage().ref(pathToFile);
|
|
227
|
-
const childRef = ref.child(fileName);
|
|
228
|
-
return childRef.delete()
|
|
229
|
-
}
|
|
230
357
|
|
|
231
358
|
}
|
|
@@ -365,7 +365,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
|
|
|
365
365
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
366
366
|
} else {
|
|
367
367
|
if (message.attributes.messagelabel.parameters.firstname) {
|
|
368
|
-
// other user has been added to the group (and he has a
|
|
368
|
+
// other user has been added to the group (and he has a fullname)
|
|
369
369
|
subject = message.attributes.messagelabel.parameters.firstname;
|
|
370
370
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
371
371
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
@@ -16,7 +16,7 @@ export class NativeImageRepoService extends ImageRepoService {
|
|
|
16
16
|
* @param uid
|
|
17
17
|
*/
|
|
18
18
|
getImagePhotoUrl(uid: string): string {
|
|
19
|
-
this.baseImageURL = this.getImageBaseUrl() + '
|
|
19
|
+
this.baseImageURL = this.getImageBaseUrl() + 'files'
|
|
20
20
|
let sender_id = '';
|
|
21
21
|
if (uid.includes('bot_')) {
|
|
22
22
|
sender_id = uid.slice(4)
|