@chat21/chat21-ionic 3.0.59-rc1 → 3.0.59-rc5
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 +19 -0
- package/README.md +4 -0
- package/package.json +1 -1
- package/resources/Android/splash/drawable-land-hdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-ldpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-mdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xxxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-hdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-ldpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-mdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xxxhdpi-screen.png +0 -0
- package/resources/Android/splash.png +0 -0
- package/src/app/app-routing.module.ts +21 -17
- package/src/app/app.component.html +6 -3
- package/src/app/app.component.ts +206 -41
- package/src/app/app.module.ts +4 -1
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.html +4 -4
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.scss +8 -2
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.ts +6 -1
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html +1 -1
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +1 -1
- package/src/app/chatlib/conversation-detail/message/image/image.component.html +7 -6
- package/src/app/chatlib/conversation-detail/message/image/image.component.ts +20 -1
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +34 -5
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.scss +8 -144
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.ts +14 -18
- package/src/app/components/authentication/login/login.component.html +2 -2
- package/src/app/components/authentication/login/login.component.ts +2 -1
- package/src/app/components/conversation-detail/bubble-my-message/bubble-my-message.component.ts +1 -1
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.html +3 -2
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.ts +3 -3
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +46 -5
- package/src/app/components/image-viewer/image-viewer.component.html +23 -0
- package/src/app/components/image-viewer/image-viewer.component.scss +107 -0
- package/src/app/components/image-viewer/image-viewer.component.spec.ts +24 -0
- package/src/app/components/image-viewer/image-viewer.component.ts +38 -0
- package/src/app/components/project-item/project-item.component.html +102 -0
- package/src/app/components/project-item/project-item.component.scss +542 -0
- package/src/app/components/project-item/project-item.component.spec.ts +24 -0
- package/src/app/components/project-item/project-item.component.ts +308 -0
- package/src/app/components/utils/avatar-profile/avatar-profile.component.html +9 -3
- package/src/app/components/utils/avatar-profile/avatar-profile.component.ts +6 -4
- package/src/app/pages/authentication/login/login.page.ts +1 -1
- package/src/app/pages/conversation-detail/conversation-detail.page.html +5 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +122 -30
- package/src/app/pages/conversations-list/conversations-list.page.html +40 -24
- package/src/app/pages/conversations-list/conversations-list.page.scss +146 -1
- package/src/app/pages/conversations-list/conversations-list.page.ts +80 -6
- package/src/app/pages/unassigned-conversations/unassigned-conversations-routing.module.ts +17 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.module.ts +22 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.html +14 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +0 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.spec.ts +24 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.ts +105 -0
- package/src/app/services/nav-proxy.service.ts +1 -1
- package/src/app/services/tiledesk/tiledesk.service.ts +22 -1
- package/src/app/services/websocket/websocket-js.ts +559 -0
- package/src/app/services/websocket/websocket.service.spec.ts +12 -0
- package/src/app/services/websocket/websocket.service.ts +274 -0
- package/src/app/shared/shared.module.ts +7 -1
- package/src/assets/i18n/en.json +8 -1
- package/src/assets/i18n/it.json +8 -1
- package/src/chat21-core/providers/chat-manager.ts +3 -3
- package/src/chat21-core/providers/firebase/firebase-archivedconversations-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-auth-service.ts +3 -3
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-notifications.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-presence.service.ts +2 -2
- package/src/chat21-core/providers/firebase/firebase-typing.service.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +1 -1
- package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +1 -1
- package/src/chat21-core/utils/utils.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# chat21-ionic ver 3.0
|
|
2
2
|
|
|
3
|
+
### 3.0.59-rc5
|
|
4
|
+
- Display a "toast message" of success after that the agent has joined to an unassigned conversation
|
|
5
|
+
|
|
6
|
+
### 3.0.59-rc4
|
|
7
|
+
- Adds an item to the top of the conversation list that shows the number of unassigned conversations for a selected project
|
|
8
|
+
- Adds the ability, by clicking on the element that displays the number of unassigned conversations, to view the unassigned conversations and to join to them or archive them
|
|
9
|
+
|
|
10
|
+
### 3.0.59-rc3
|
|
11
|
+
- Improves the method that allows to chain multiple canned responses
|
|
12
|
+
|
|
13
|
+
### 3.0.59-rc2
|
|
14
|
+
- Fixes the bug: on small windows, images and iframes are not the same size as the bubble message that contains them
|
|
15
|
+
- Adds in the "bubble-message" component a check if the metadata is an object before calling the getMetadataSize() method
|
|
16
|
+
- Hides the "canned responses" if there are whitespace after the forward slash "/" or if there are no whitespace before the forward slash "/"
|
|
17
|
+
- Fixes the bug: if the "canned responses" are selected with the mouse, the "send message" text area does not have focus
|
|
18
|
+
- Adds the image viewer and the ability to download an image from it
|
|
19
|
+
- Fixes the position of the "archive" button when the app runs on mobile devices
|
|
20
|
+
- Updates Android splash screen .png image
|
|
21
|
+
|
|
3
22
|
### 3.0.59-rc1
|
|
4
23
|
- Fixes the bug: the "send message" button remains in the "disabled" state even if it is active
|
|
5
24
|
- Changes the format of the date displayed in the message tooltips
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
[](https://badge.fury.io/js/%40chat21%2Fchat21-ionic)
|
|
2
2
|
|
|
3
|
+
> ***🚀 Do you want to install Tiledesk on your server with just one click?***
|
|
4
|
+
>
|
|
5
|
+
> ***Use [Docker Compose Tiledesk installation](https://github.com/Tiledesk/tiledesk-deployment/blob/master/docker-compose/README.md) guide***
|
|
6
|
+
|
|
3
7
|
Chat21 is the core of the open source live chat platform [Tiledesk.com](http://www.tiledesk.com).
|
|
4
8
|
|
|
5
9
|
# Features #
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -29,6 +29,27 @@ const routes: Routes = [
|
|
|
29
29
|
loadChildren: './pages/conversation-detail/conversation-detail.module#ConversationDetailPageModule'
|
|
30
30
|
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
path: 'contacts-directory',
|
|
34
|
+
loadChildren: () => import('./pages/contacts-directory/contacts-directory.module').then( m => m.ContactsDirectoryPageModule)
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
path: 'login',
|
|
38
|
+
loadChildren: () => import('./pages/authentication/login/login.module').then( m => m.LoginPageModule)
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
path: 'profile-info',
|
|
42
|
+
loadChildren: () => import('./pages/profile-info/profile-info.module').then( m => m.ProfileInfoPageModule)
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
path: 'loader-preview',
|
|
46
|
+
loadChildren: () => import('./pages/loader-preview/loader-preview.module').then( m => m.LoaderPreviewPageModule)
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
path: 'unassigned-conversations',
|
|
50
|
+
loadChildren: () => import('./pages/unassigned-conversations/unassigned-conversations.module').then( m => m.UnassignedConversationsPageModule)
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
|
|
33
54
|
// {
|
|
34
55
|
// path: 'conversation-detail/:IDConv',
|
|
@@ -50,23 +71,6 @@ const routes: Routes = [
|
|
|
50
71
|
// // loadChildren: () => import('./pages/details/details.module').then( m => m.DetailsPageModule),
|
|
51
72
|
// // loadChildren: './pages/details/details.module',
|
|
52
73
|
// },
|
|
53
|
-
{
|
|
54
|
-
path: 'contacts-directory',
|
|
55
|
-
loadChildren: () => import('./pages/contacts-directory/contacts-directory.module').then( m => m.ContactsDirectoryPageModule)
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
path: 'login',
|
|
59
|
-
loadChildren: () => import('./pages/authentication/login/login.module').then( m => m.LoginPageModule)
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
path: 'profile-info',
|
|
63
|
-
loadChildren: () => import('./pages/profile-info/profile-info.module').then( m => m.ProfileInfoPageModule)
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
path: 'loader-preview',
|
|
67
|
-
loadChildren: () => import('./pages/loader-preview/loader-preview.module').then( m => m.LoaderPreviewPageModule)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
74
|
|
|
71
75
|
|
|
72
76
|
// {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<ion-app>
|
|
2
|
-
<div
|
|
2
|
+
<div>
|
|
3
|
+
<!-- (click)="hideAlert()" -->
|
|
4
|
+
<app-image-viewer></app-image-viewer>
|
|
3
5
|
<ion-split-pane when="md" contentId="main">
|
|
6
|
+
|
|
4
7
|
<ion-nav #sidebarNav [root]="sidebarPage"></ion-nav>
|
|
5
8
|
<!-- our side menu -->
|
|
6
9
|
<!-- <ion-router-outlet id="sidebar" name='sidebar' animated="false" #masterNav> -->
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
<!-- <app-conversations-list></app-conversations-list> -->
|
|
11
|
+
<!-- <app-details></app-details> -->
|
|
9
12
|
<!-- </ion-router-outlet> -->
|
|
10
13
|
<!-- the main content -->
|
|
11
14
|
<ion-router-outlet id="main" #detailNav animated="false">
|
package/src/app/app.component.ts
CHANGED
|
@@ -55,9 +55,8 @@ import { getImageUrlThumbFromFirebasestorage } from 'src/chat21-core/utils/utils
|
|
|
55
55
|
import { TiledeskService } from './services/tiledesk/tiledesk.service';
|
|
56
56
|
import { NetworkService } from './services/network-service/network.service';
|
|
57
57
|
import * as PACKAGE from 'package.json';
|
|
58
|
-
|
|
59
|
-
import {
|
|
60
|
-
import { filter, takeUntil } from 'rxjs/operators'
|
|
58
|
+
import { filter } from 'rxjs/operators'
|
|
59
|
+
import { WebSocketJs } from './services/websocket/websocket-js';
|
|
61
60
|
|
|
62
61
|
// import { filter } from 'rxjs/operators';
|
|
63
62
|
|
|
@@ -99,9 +98,11 @@ export class AppComponent implements OnInit {
|
|
|
99
98
|
public missingConnectionToast: any
|
|
100
99
|
public executedInitializeAppByWatchConnection: boolean = false;
|
|
101
100
|
private version: string;
|
|
102
|
-
|
|
101
|
+
|
|
103
102
|
// private isOnline: boolean = false;
|
|
104
103
|
|
|
104
|
+
wsService: WebSocketJs;
|
|
105
|
+
|
|
105
106
|
constructor(
|
|
106
107
|
private platform: Platform,
|
|
107
108
|
private splashScreen: SplashScreen,
|
|
@@ -136,34 +137,105 @@ export class AppComponent implements OnInit {
|
|
|
136
137
|
public toastController: ToastController,
|
|
137
138
|
// private network: Network,
|
|
138
139
|
// private tiledeskService: TiledeskService,
|
|
139
|
-
private networkService: NetworkService
|
|
140
|
+
private networkService: NetworkService,
|
|
141
|
+
public webSocketJs: WebSocketJs,
|
|
140
142
|
) {
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
// t.dismiss();
|
|
147
|
-
// });
|
|
143
|
+
|
|
144
|
+
// this.saveInStorageChatOpenedTab();
|
|
145
|
+
// FOR TEST
|
|
146
|
+
// const last_project = { "user_available": true, "number_assigned_requests": 59, "last_login_at": "2021-08-09T17:30:55.234Z", "status": "active", "_id": "6112bc8f58c958003495a2cb", "id_project": { "status": 100, "_id": "60ffe291f725db00347661ef", "name": "27-LUGLIO-21-STRIPE-TEST", "activeOperatingHours": false, "createdBy": "608ad02d3a4dc000344ade17", "profile": { "name": "pro", "trialDays": 30, "agents": 5, "type": "payment", "subStart": "2021-11-18T10:42:41.000Z", "subEnd": "2021-11-19T10:42:41.000Z", "subscriptionId": "sub_Jvf4kABe9t8JvX", "last_stripe_event": "invoice.payment_succeeded" }, "versions": 20115, "channels": [{ "name": "chat21" }], "createdAt": "2021-07-27T10:40:17.752Z", "updatedAt": "2021-11-18T11:55:01.346Z", "__v": 0, "widget": { "preChatForm": true, "preChatFormJson": [{ "name": "userFullname", "type": "text", "mandatory": true, "label": { "en": "Your name", "it": "Il tuo nome" } }, { "name": "userEmail", "type": "text", "mandatory": true, "regex": "/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/", "label": { "en": "Your email", "it": "La tua email" }, "errorLabel": { "en": "Invalid email address", "it": "Indirizzo email non valido" } }, { "name": "tel", "mandatory": true, "label": { "en": "Your phone number", "it": "Il tuo numero di telefono" } }], "preChatFormCustomFieldsEnabled": true }, "trialExpired": true, "trialDaysLeft": 84, "isActiveSubscription": true, "id": "60ffe291f725db00347661ef" }, "id_user": "60aa0fef1482fe00346854a7", "role": "admin", "createdBy": "608ad02d3a4dc000344ade17", "createdAt": "2021-08-10T17:51:11.318Z", "updatedAt": "2021-11-19T08:08:21.437Z", "__v": 0, "presence": { "status": "online", "changedAt": "2021-11-19T08:08:21.432Z" }, "isAuthenticated": true, "id": "6112bc8f58c958003495a2cb" }
|
|
147
|
+
// localStorage.setItem('last_project', JSON.stringify(last_project))
|
|
148
148
|
}
|
|
149
|
+
saveInStorageChatOpenedTab() {
|
|
150
|
+
// if (+localStorage.tabCount > 0) {
|
|
151
|
+
// alert('Already open!');
|
|
152
|
+
// } else {
|
|
153
|
+
// localStorage.tabCount = 0;
|
|
154
|
+
// }
|
|
155
|
+
|
|
156
|
+
// window.addEventListener('load', (event) => {
|
|
157
|
+
// console.log('[CONVS-LIST-PAGE] page is fully loaded', event);
|
|
158
|
+
// // let tab = + localStorage.getItem('tab')
|
|
159
|
+
// // console.log('[CONVS-LIST-PAGE] page is fully loaded getItem tab', + tab);
|
|
160
|
+
// // localStorage.setItem('tab', "1" )
|
|
161
|
+
// localStorage.tabCount = +localStorage.tabCount + 1;
|
|
162
|
+
// });
|
|
163
|
+
|
|
164
|
+
// // https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-beforeunload-event
|
|
165
|
+
// const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
|
|
166
|
+
// window.addEventListener(terminationEvent, (event) => {
|
|
167
|
+
// console.log('[CONVS-LIST-PAGE] page is terminationEvent', event);
|
|
168
|
+
// localStorage.tabCount = +localStorage.tabCount - 1;
|
|
169
|
+
// }, { capture: true });
|
|
170
|
+
const getState = () => {
|
|
171
|
+
if (document.visibilityState === 'hidden') {
|
|
172
|
+
return 'hidden';
|
|
173
|
+
}
|
|
174
|
+
if (document.hasFocus()) {
|
|
175
|
+
return 'active';
|
|
176
|
+
}
|
|
177
|
+
return 'passive';
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
let state = getState();
|
|
181
|
+
console.log('[CONVS-LIST-PAGE] page state ', state)
|
|
182
|
+
if (state === 'hidden') {
|
|
183
|
+
localStorage.setItem('hidden', 'true')
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const logStateChange = (nextState) => {
|
|
187
|
+
const prevState = state;
|
|
188
|
+
if (nextState !== prevState) {
|
|
189
|
+
console.log(`State change: ${prevState} >>> ${nextState}`);
|
|
190
|
+
state = nextState;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
|
|
195
|
+
window.addEventListener(type, () => logStateChange(getState()), { capture: true });
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// The next two listeners, on the other hand, can determine the next
|
|
199
|
+
// state from the event itself.
|
|
200
|
+
window.addEventListener('freeze', () => {
|
|
201
|
+
// In the freeze event, the next state is always frozen.
|
|
202
|
+
logStateChange('frozen');
|
|
203
|
+
}, { capture: true });
|
|
204
|
+
|
|
205
|
+
window.addEventListener('pagehide', (event) => {
|
|
206
|
+
if (event.persisted) {
|
|
207
|
+
// If the event's persisted property is `true` the page is about
|
|
208
|
+
// to enter the Back-Forward Cache, which is also in the frozen state.
|
|
209
|
+
logStateChange('frozen');
|
|
210
|
+
localStorage.setItem('terminated', 'true')
|
|
211
|
+
} else {
|
|
212
|
+
// If the event's persisted property is not `true` the page is
|
|
213
|
+
// about to be unloaded.
|
|
214
|
+
logStateChange('terminated');
|
|
215
|
+
localStorage.setItem('terminated', 'true')
|
|
216
|
+
}
|
|
217
|
+
}, { capture: true });
|
|
149
218
|
|
|
150
|
-
param() {
|
|
151
|
-
// PARAM
|
|
152
|
-
const url: URL = new URL(window.top.location.href);
|
|
153
|
-
const params: URLSearchParams = url.searchParams;
|
|
154
|
-
return params;
|
|
155
219
|
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
// param() {
|
|
223
|
+
// // PARAM
|
|
224
|
+
// const url: URL = new URL(window.top.location.href);
|
|
225
|
+
// const params: URLSearchParams = url.searchParams;
|
|
226
|
+
// return params;
|
|
227
|
+
// }
|
|
156
228
|
/**
|
|
157
229
|
*/
|
|
158
230
|
ngOnInit() {
|
|
159
231
|
const appconfig = this.appConfigProvider.getConfig();
|
|
160
232
|
this.persistence = appconfig.authPersistence;
|
|
161
233
|
this.appStorageService.initialize(environment.storage_prefix, this.persistence, '')
|
|
162
|
-
this.logger.log('[APP-COMP] HELLO ngOnInit !!!!!!!')
|
|
163
|
-
this.logger.
|
|
234
|
+
// this.logger.log('[APP-COMP] HELLO ngOnInit !!!!!!!')
|
|
235
|
+
// this.logger.log('[APP-COMP] ngOnInit this.route.snapshot.params -->', this.route.snapshot.params);
|
|
164
236
|
// this.initializeApp('oninit');
|
|
165
237
|
const token = getParameterByName('jwt')
|
|
166
|
-
this.logger.
|
|
238
|
+
// this.logger.log('[APP-COMP] ngOnInit AUTOLOGIN token get with getParameterByName -->', token);
|
|
167
239
|
|
|
168
240
|
if (token) {
|
|
169
241
|
// this.isOnline = false;
|
|
@@ -182,9 +254,81 @@ export class AppComponent implements OnInit {
|
|
|
182
254
|
}
|
|
183
255
|
this.initializeApp('oninit');
|
|
184
256
|
|
|
257
|
+
this.listenToPostMsgs();
|
|
185
258
|
}
|
|
186
259
|
|
|
187
260
|
|
|
261
|
+
|
|
262
|
+
listenToPostMsgs() {
|
|
263
|
+
window.addEventListener("message", (event) => {
|
|
264
|
+
console.log("[APP-COMP] message event ", event);
|
|
265
|
+
|
|
266
|
+
if (event && event.data && event.data.action && event.data.parameter) {
|
|
267
|
+
if (event.data.action === 'openJoinConversationModal') {
|
|
268
|
+
console.log("[APP-COMP] message event action ", event.data.action);
|
|
269
|
+
console.log("[APP-COMP] message event parameter ", event.data.parameter);
|
|
270
|
+
this.presentAlertConfirmJoinRequest(event.data.parameter, event.data.calledBy)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (event && event.data && event.data.action && event.data.text) {
|
|
274
|
+
if (event.data.action === "display_toast_join_complete") {
|
|
275
|
+
this.presentToastJoinComplete(event.data.text)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async presentToastJoinComplete(text) {
|
|
282
|
+
const toast = await this.toastController.create({
|
|
283
|
+
message: text,
|
|
284
|
+
duration: 2000,
|
|
285
|
+
color: "success"
|
|
286
|
+
});
|
|
287
|
+
toast.present();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async presentAlertConfirmJoinRequest(requestid, calledby) {
|
|
291
|
+
var iframeWin = <HTMLIFrameElement>document.getElementById("unassigned-convs-iframe")
|
|
292
|
+
// console.log("[APP-COMP] message event iframeWin ", iframeWin);
|
|
293
|
+
|
|
294
|
+
const isIFrame = (input: HTMLElement | null): input is HTMLIFrameElement =>
|
|
295
|
+
input !== null && input.tagName === 'IFRAME';
|
|
296
|
+
|
|
297
|
+
const keys = ['YouAreAboutToJoinThisChat', 'Cancel', 'AreYouSure'];
|
|
298
|
+
const translationMap = this.translateService.translateLanguage(keys);
|
|
299
|
+
|
|
300
|
+
const alert = await this.alertController.create({
|
|
301
|
+
cssClass: 'my-custom-class',
|
|
302
|
+
header: translationMap.get('AreYouSure'),
|
|
303
|
+
message: translationMap.get('YouAreAboutToJoinThisChat'),
|
|
304
|
+
buttons: [
|
|
305
|
+
{
|
|
306
|
+
text: translationMap.get('Cancel'),
|
|
307
|
+
role: 'cancel',
|
|
308
|
+
cssClass: 'secondary',
|
|
309
|
+
handler: (blah) => {
|
|
310
|
+
// console.log('Confirm Cancel: blah', blah);
|
|
311
|
+
}
|
|
312
|
+
}, {
|
|
313
|
+
text: 'Ok',
|
|
314
|
+
handler: () => {
|
|
315
|
+
// console.log('Confirm Okay');
|
|
316
|
+
|
|
317
|
+
if (isIFrame(iframeWin) && iframeWin.contentWindow) {
|
|
318
|
+
const msg = { action: "joinConversation", parameter: requestid, calledBy: calledby }
|
|
319
|
+
iframeWin.contentWindow.postMessage(msg, '*');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
await alert.present();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
188
332
|
signInWithCustomToken(token) {
|
|
189
333
|
// this.isOnline = false;
|
|
190
334
|
this.logger.log('[APP-COMP] SIGNINWITHCUSTOMTOKEN token', token)
|
|
@@ -200,8 +344,8 @@ export class AppComponent implements OnInit {
|
|
|
200
344
|
|
|
201
345
|
/** */
|
|
202
346
|
initializeApp(calledby: string) {
|
|
203
|
-
this.logger.log('[APP-COMP] - X - initializeApp !!! CALLED-BY: ', calledby);
|
|
204
|
-
this.logger.log('[APP-COMP] appconfig platform is cordova: ', this.platform.is('cordova'))
|
|
347
|
+
// this.logger.log('[APP-COMP] - X - initializeApp !!! CALLED-BY: ', calledby);
|
|
348
|
+
// this.logger.log('[APP-COMP] appconfig platform is cordova: ', this.platform.is('cordova'))
|
|
205
349
|
|
|
206
350
|
if (!this.platform.is('cordova')) {
|
|
207
351
|
this.splashScreen.show();
|
|
@@ -211,7 +355,7 @@ export class AppComponent implements OnInit {
|
|
|
211
355
|
this.getRouteParamsAndSetLoggerConfig();
|
|
212
356
|
|
|
213
357
|
const appconfig = this.appConfigProvider.getConfig();
|
|
214
|
-
this.logger.info('[APP-COMP] appconfig: ', appconfig)
|
|
358
|
+
// this.logger.info('[APP-COMP] appconfig: ', appconfig)
|
|
215
359
|
this.version = PACKAGE.version;
|
|
216
360
|
this.logger.info('[APP-COMP] version: ', this.version)
|
|
217
361
|
|
|
@@ -320,9 +464,9 @@ export class AppComponent implements OnInit {
|
|
|
320
464
|
getRouteParamsAndSetLoggerConfig() {
|
|
321
465
|
const appconfig = this.appConfigProvider.getConfig();
|
|
322
466
|
this.route.queryParams.subscribe(params => {
|
|
323
|
-
this.logger.
|
|
467
|
+
// this.logger.log('[APP-COMP] getRouteParamsAndSetLoggerConfig - queryParams params: ', params)
|
|
324
468
|
if (params.logLevel) {
|
|
325
|
-
this.logger.
|
|
469
|
+
this.logger.log('[APP-COMP] getRouteParamsAndSetLoggerConfig - log level get from queryParams: ', params.logLevel)
|
|
326
470
|
this.logger.setLoggerConfig(true, params.logLevel)
|
|
327
471
|
} else {
|
|
328
472
|
this.logger.info('[APP-COMP] getRouteParamsAndSetLoggerConfig - log level get from appconfig: ', appconfig.logLevel)
|
|
@@ -352,6 +496,7 @@ export class AppComponent implements OnInit {
|
|
|
352
496
|
/**------- AUTHENTICATION FUNCTIONS --> START <--- +*/
|
|
353
497
|
private initAuthentication() {
|
|
354
498
|
const tiledeskToken = this.appStorageService.getItem('tiledeskToken')
|
|
499
|
+
|
|
355
500
|
this.logger.log('[APP-COMP] >>> INIT-AUTHENTICATION !!! ')
|
|
356
501
|
this.logger.log('[APP-COMP] >>> initAuthentication tiledeskToken ', tiledeskToken)
|
|
357
502
|
// const currentUser = JSON.parse(this.appStorageService.getItem('currentUser'));
|
|
@@ -360,19 +505,19 @@ export class AppComponent implements OnInit {
|
|
|
360
505
|
this.logger.log('[APP-COMP] >>> initAuthentication I LOG IN WITH A TOKEN EXISTING IN THE LOCAL STORAGE OR WITH A TOKEN PASSED IN THE URL PARAMETERS <<<')
|
|
361
506
|
this.tiledeskAuthService.signInWithCustomToken(tiledeskToken).then(user => {
|
|
362
507
|
this.logger.log('[APP-COMP] >>> initAuthentication user ', user)
|
|
363
|
-
this.messagingAuthService.createCustomToken(tiledeskToken)
|
|
508
|
+
this.messagingAuthService.createCustomToken(tiledeskToken)
|
|
364
509
|
}).catch(error => {
|
|
365
510
|
this.logger.error('[APP-COMP] initAuthentication SIGNINWITHCUSTOMTOKEN error::', error)
|
|
366
511
|
})
|
|
367
512
|
} else {
|
|
368
513
|
this.logger.warn('[APP-COMP] >>> I AM NOT LOGGED IN <<<')
|
|
369
|
-
|
|
514
|
+
|
|
370
515
|
// clearTimeout(this.timeModalLogin);
|
|
371
516
|
// this.timeModalLogin = setTimeout(() => {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
517
|
+
if (!this.hadBeenCalledOpenModal) {
|
|
518
|
+
this.authModal = this.presentModal('initAuthentication');
|
|
519
|
+
this.hadBeenCalledOpenModal = true;
|
|
520
|
+
}
|
|
376
521
|
// }, 1000);
|
|
377
522
|
}
|
|
378
523
|
}
|
|
@@ -385,6 +530,16 @@ export class AppComponent implements OnInit {
|
|
|
385
530
|
// }
|
|
386
531
|
// }
|
|
387
532
|
|
|
533
|
+
connetWebsocket(tiledeskToken) {
|
|
534
|
+
const WS_URL = 'wss://tiledesk-server-pre.herokuapp.com/' + '?token=' + tiledeskToken
|
|
535
|
+
this.webSocketJs.init(
|
|
536
|
+
WS_URL,
|
|
537
|
+
undefined,
|
|
538
|
+
undefined,
|
|
539
|
+
undefined
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
388
543
|
/**
|
|
389
544
|
* goOnLine:
|
|
390
545
|
* 1 - nascondo splashscreen
|
|
@@ -396,8 +551,10 @@ export class AppComponent implements OnInit {
|
|
|
396
551
|
// this.isOnline = true;
|
|
397
552
|
// this.logger.info('initialize FROM [APP-COMP] - [APP-COMP] - GO-ONLINE isOnline ', this.isOnline);
|
|
398
553
|
|
|
399
|
-
clearTimeout(this.timeModalLogin);
|
|
554
|
+
// clearTimeout(this.timeModalLogin);
|
|
400
555
|
const tiledeskToken = this.tiledeskAuthService.getTiledeskToken();
|
|
556
|
+
this.connetWebsocket(tiledeskToken)
|
|
557
|
+
|
|
401
558
|
const currentUser = this.tiledeskAuthService.getCurrentUser();
|
|
402
559
|
// this.logger.printDebug('APP-COMP - goOnLine****', currentUser);
|
|
403
560
|
this.logger.log('[APP-COMP] - GO-ONLINE - currentUser ', currentUser);
|
|
@@ -429,8 +586,16 @@ export class AppComponent implements OnInit {
|
|
|
429
586
|
this.chatManager.startApp();
|
|
430
587
|
}
|
|
431
588
|
|
|
589
|
+
|
|
590
|
+
webSocketClose() {
|
|
591
|
+
this.logger.log('[APP-COMP] - GO-OFFLINE - webSocketClose');
|
|
592
|
+
this.webSocketJs.close()
|
|
593
|
+
}
|
|
594
|
+
|
|
432
595
|
goOffLine = () => {
|
|
433
596
|
this.logger.log('[APP-COMP] - GO-OFFLINE');
|
|
597
|
+
|
|
598
|
+
this.webSocketClose()
|
|
434
599
|
// this.isOnline = false;
|
|
435
600
|
// this.conversationsHandlerService.conversations = [];
|
|
436
601
|
|
|
@@ -439,13 +604,13 @@ export class AppComponent implements OnInit {
|
|
|
439
604
|
this.chatManager.goOffLine();
|
|
440
605
|
|
|
441
606
|
this.router.navigateByUrl('conversation-detail/'); //redirect to basePage
|
|
442
|
-
|
|
607
|
+
|
|
443
608
|
// clearTimeout(this.timeModalLogin);
|
|
444
609
|
// this.timeModalLogin = setTimeout(() => {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
610
|
+
if (!this.hadBeenCalledOpenModal) {
|
|
611
|
+
this.authModal = this.presentModal('goOffLine');
|
|
612
|
+
this.hadBeenCalledOpenModal = true
|
|
613
|
+
}
|
|
449
614
|
// }, 1000);
|
|
450
615
|
|
|
451
616
|
// this.unsubscribe$.next();
|
|
@@ -601,8 +766,8 @@ export class AppComponent implements OnInit {
|
|
|
601
766
|
return;
|
|
602
767
|
}
|
|
603
768
|
|
|
604
|
-
this.BSAuthStateChangedSubscriptionRef = this.messagingAuthService.BSAuthStateChanged
|
|
605
|
-
|
|
769
|
+
this.BSAuthStateChangedSubscriptionRef = this.messagingAuthService.BSAuthStateChanged
|
|
770
|
+
|
|
606
771
|
// .pipe(takeUntil(this.unsubscribe$))
|
|
607
772
|
.pipe(filter((state) => state !== null))
|
|
608
773
|
.subscribe((state: any) => {
|
|
@@ -658,7 +823,7 @@ export class AppComponent implements OnInit {
|
|
|
658
823
|
* apro dettaglio conversazione
|
|
659
824
|
*/
|
|
660
825
|
subscribeChangedConversationSelected = (user: UserModel, type: string) => {
|
|
661
|
-
this.logger.
|
|
826
|
+
this.logger.log('[APP-COMP] subscribeUidConvSelectedChanged navigateByUrl', user, type);
|
|
662
827
|
// this.router.navigateByUrl('conversation-detail/' + user.uid + '?conversationWithFullname=' + user.fullname);
|
|
663
828
|
this.router.navigateByUrl('conversation-detail/' + user.uid + '/' + user.fullname + '/' + type);
|
|
664
829
|
}
|
|
@@ -877,7 +1042,7 @@ export class AppComponent implements OnInit {
|
|
|
877
1042
|
// this.unsubscribe$.complete();
|
|
878
1043
|
this.initializeApp('onstoragechanged');
|
|
879
1044
|
|
|
880
|
-
|
|
1045
|
+
|
|
881
1046
|
|
|
882
1047
|
// console.log('[APP-COMP] onAuthStateChanged HERE !!! ')
|
|
883
1048
|
// firebase.auth().onAuthStateChanged(user => {
|
package/src/app/app.module.ts
CHANGED
|
@@ -94,7 +94,8 @@ import { TooltipModule } from 'ng2-tooltip-directive';
|
|
|
94
94
|
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
95
95
|
import { Network } from '@ionic-native/network/ngx';
|
|
96
96
|
import { ConnectionService } from 'ng-connection-service';
|
|
97
|
-
|
|
97
|
+
import { WebSocketJs } from './services/websocket/websocket-js';
|
|
98
|
+
import { UnassignedConversationsPageModule } from './pages/unassigned-conversations/unassigned-conversations.module';
|
|
98
99
|
|
|
99
100
|
// FACTORIES
|
|
100
101
|
export function createTranslateLoader(http: HttpClient) {
|
|
@@ -253,6 +254,7 @@ const appInitializerFn = (appConfig: AppConfigProvider, logger: NGXLogger) => {
|
|
|
253
254
|
LoginPageModule,
|
|
254
255
|
ConversationListPageModule,
|
|
255
256
|
ConversationDetailPageModule,
|
|
257
|
+
UnassignedConversationsPageModule,
|
|
256
258
|
TranslateModule.forRoot({
|
|
257
259
|
loader: {
|
|
258
260
|
provide: TranslateLoader,
|
|
@@ -352,6 +354,7 @@ const appInitializerFn = (appConfig: AppConfigProvider, logger: NGXLogger) => {
|
|
|
352
354
|
EventsService,
|
|
353
355
|
Chooser,
|
|
354
356
|
Chat21Service,
|
|
357
|
+
WebSocketJs
|
|
355
358
|
]
|
|
356
359
|
})
|
|
357
360
|
export class AppModule { }
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
<div role="messaggio" *ngIf="messageType(MESSAGE_TYPE_MINE, message)" class="msg_container base_sent">
|
|
68
68
|
|
|
69
69
|
<!--backgroundColor non viene ancora usato -->
|
|
70
|
-
<chat-bubble-message
|
|
71
|
-
|
|
70
|
+
<chat-bubble-message [ngClass]="{'has-metadata': (isImage(message) || isFrame(message))}"
|
|
71
|
+
class="messages msg_sent" id="message_msg_sent"
|
|
72
72
|
[ngClass]="{'button-in-msg' : message.metadata && message.metadata.button}" [message]="message"
|
|
73
73
|
[textColor]="'col-msg-sent'"
|
|
74
74
|
(onBeforeMessageRender)="returnOnBeforeMessageRender($event)"
|
|
@@ -98,8 +98,8 @@
|
|
|
98
98
|
</chat-avatar-image> -->
|
|
99
99
|
|
|
100
100
|
<!--backgroundColor non viene ancora usato -->
|
|
101
|
-
|
|
102
|
-
<chat-bubble-message class="messages msg_receive"
|
|
101
|
+
|
|
102
|
+
<chat-bubble-message [ngClass]="{'has-metadata': (isImage(message) || isFrame(message))}" class="messages msg_receive" id="message_msg_receive"
|
|
103
103
|
[message]="message"
|
|
104
104
|
[textColor]="'black'"
|
|
105
105
|
(onBeforeMessageRender)="returnOnBeforeMessageRender($event)"
|
|
@@ -93,7 +93,9 @@ ion-item {
|
|
|
93
93
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
.has-metadata {
|
|
97
|
+
max-width: 100% !important;
|
|
98
|
+
}
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
/** recive message **/
|
|
@@ -138,7 +140,11 @@ ion-item {
|
|
|
138
140
|
border-top-left-radius: 8px;
|
|
139
141
|
border-bottom-left-radius: 0px;
|
|
140
142
|
|
|
141
|
-
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.has-metadata {
|
|
146
|
+
max-width: 100% !important;
|
|
147
|
+
}
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
.time{
|
|
@@ -5,6 +5,7 @@ import { ChangeDetectorRef, Component, Input, OnInit, Output, EventEmitter} from
|
|
|
5
5
|
import { MESSAGE_TYPE_INFO, MESSAGE_TYPE_MINE, MESSAGE_TYPE_OTHERS } from 'src/chat21-core/utils/constants';
|
|
6
6
|
import { isChannelTypeGroup, isFirstMessage, isInfo, isMine, messageType } from 'src/chat21-core/utils/utils-message';
|
|
7
7
|
import { UploadService } from 'src/chat21-core/providers/abstract/upload.service';
|
|
8
|
+
import { isFile, isFrame, isImage } from 'src/chat21-core/utils/utils-message';
|
|
8
9
|
|
|
9
10
|
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
10
11
|
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
@@ -25,6 +26,10 @@ export class IonConversationDetailComponent extends ConversationContentComponent
|
|
|
25
26
|
public uploadProgress: number = 100
|
|
26
27
|
public fileType: any
|
|
27
28
|
|
|
29
|
+
isImage = isImage;
|
|
30
|
+
isFile = isFile;
|
|
31
|
+
isFrame = isFrame;
|
|
32
|
+
|
|
28
33
|
isMine = isMine;
|
|
29
34
|
isInfo = isInfo;
|
|
30
35
|
isFirstMessage = isFirstMessage;
|
|
@@ -34,7 +39,7 @@ export class IonConversationDetailComponent extends ConversationContentComponent
|
|
|
34
39
|
MESSAGE_TYPE_INFO = MESSAGE_TYPE_INFO;
|
|
35
40
|
MESSAGE_TYPE_MINE = MESSAGE_TYPE_MINE;
|
|
36
41
|
MESSAGE_TYPE_OTHERS = MESSAGE_TYPE_OTHERS;
|
|
37
|
-
|
|
42
|
+
logger: LoggerService = LoggerInstance.getInstance()
|
|
38
43
|
/**
|
|
39
44
|
* Constructor
|
|
40
45
|
* @param cdref
|
package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- [ngClass]="{'button-in-msg' : message.metadata && message.metadata.button}" -->
|
|
2
2
|
<!-- [ngStyle]="{'padding': (isImage(message) || isFrame(message))?'0px':'0 8px'}" -->
|
|
3
3
|
<!-- isImage >{{isImage(message) }} message.metadata.width {{message?.metadata?.width }} -->
|
|
4
|
-
<div
|
|
4
|
+
<div id="bubble-message" [ngStyle]="{'padding': (isImage(message) || isFrame(message))?'0px':'0 8px', 'width': (isImage(message) || isFrame(message))? message?.metadata?.width + 'px' : null }"
|
|
5
5
|
class="messages primary-color"
|
|
6
6
|
[class.emoticon]="message?.emoticon">
|
|
7
7
|
|
package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts
CHANGED
|
@@ -87,7 +87,7 @@ export class BubbleMessageComponent implements OnInit, OnChanges {
|
|
|
87
87
|
|
|
88
88
|
ngOnChanges() {
|
|
89
89
|
// console.log('BUBBLE-MSG Hello !!!! this.message ', this.message)
|
|
90
|
-
if (this.message && this.message.metadata) {
|
|
90
|
+
if (this.message && this.message.metadata && typeof this.message.metadata === 'object') {
|
|
91
91
|
this.getMetadataSize(this.message.metadata)
|
|
92
92
|
// console.log('BUBBLE-MSG ngOnChanges message > metadata', this.message.metadata)
|
|
93
93
|
}
|